Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Начинаем веб-программирование не падая лицом в грязь. (https://forum.antichat.xyz/showthread.php?t=36338)

GreenBear 25.03.2007 16:11

Начинаем веб-программирование не падая лицом в грязь.
 
Начинаем веб-программирование не падая лицом в грязь.

В статье примеры будут на php, как на самом популярном языке среди программирования для веб.

Нужно обрабатывать все данные, которые как либо будут участвовать в sql-запросах, которые будут участвовать в открытии файлов, выводится на страницу. Не надо забивать даже на мелкие детали – это лишь увеличит ваше «забей» в дальнейшем.

SQL-Injections


Давайте рассмотрим простой пример:
PHP код:

$id  $_REQUEST['id'];
$result mysql_query("SELECT title, text, dateline, autor FROM `news` WHERE `id`='$id'"); 

Хм, что-то не так, не правда ли? Если вы не заметили, то поздравляем – в вашем проекте sql-injection, которая может привести даже к дефейсу сайта.
Этого не было бы, если бы вы обработали сразу переменную.
PHP код:

$id mysql_escpape_string($_REQUEST['id']); 

Более подробно с функцией mysql_escape_string можно ознакомится на сайте php.net

Но если значение id может быть только целым числом, зачем вообще допускать другие символы? Незачем.

Может быть так будет лучше:
PHP код:

if(!is_numeric($_REQUEST['id'])){
    
//тут сообщение об ошибке о некорректных данных
}else{
    
//если значение является целым числом, то можем продолжать без дальнейшей фильтрации за бесполезностью


А можно и вырезать все лишнее функцией intval
PHP код:

$id intval($_REQUEST['id']);
if(
$id){
    
//можно продолжать
}else{
    
//айди равно нулю


Есть мнение, и я думаю оно правильное: перед вносом в базу данных не надо обрабатывать никакие значение на вырез плохих кодов, это надо делать при выводе. В БД надо правильно вносить данные.

mysql_escape_string и mysql_real_escape_string именно для этого и созданы.

SQL-Injections нас уже не побеспокоят, перейдем дальше.

Вывод данных.

XSS это бич практически любого динамического сайта в Интернете. А все почему? Да потому что не многие считают это опасной уязвимостью (что очень и очень зря), и то, что просто забывают о том, что вместо ?page=1 злоумышленник может написать ?page=<script>evil_code</script>, который выведется на страницу.
Как обезопасится? Так же, как и в первом случае: фильтровать все данные, которые так или иначе будут выводится на странице. Тут могу порекомендовать такой же совет, как и в случае защиты от sql-inj – если значение может быть только int, то и не надо допускать другого!

В php есть несколько функций, которые вырезают html теги:
htmlspecialchars,
htmlentities,
strip_tags

Все данные, которые будут выводится на страницу должны быть отфильтрованы! Иначе безопасность вас и посетителей сайта может быть под угрозой.

Инклудинг файлов.

Из-за некорректности кода могут возникнуть и более серьезные угрозы безопасности вашего сайта, чем в предыдущем случае.
Часто из-за недостаточной обработке данных на сайтах присутствует возможность инлкуда локальных или удаленных файлов.

Если вы используете конструкцию типа приведенной ниже:
PHP код:

$file $_REQUEST['file'];
include(
$file.'.html'); 

то поздравляю – у вас инклуд-уявзвимость.
А что если мы подставим в файл http://evilhost.com/shell.php?
Правильно, на вашем сайте будет шелл :)

Как защитится? Опять же – проверять данные, переданные скрипту.
Скорее всего вам не понадобится никакие название файлов, кроме как из маски a-z
Давайте проверим переменную файл регулярным выражением, и если она пройдет проверку, то мы ее и передадим:
PHP код:

if(preg_match('/[a-z]/i'$file)) include($file.'.html');
else echo 
'Это не правильный файл!'

Если предпологается, что файлы не будут добовлятся динамически и их относительно не много, то лучше использовать функцию switch
Пример:
PHP код:

switch($_REQUEST['file']){
    case 
'eto': include('files/eto.html'); break; // Если файл – eto, ниже соотвественно
    
case 'tolko': include('files/tolko.html'); break;
    case 
'na4alo': include('files/na4alo.html'); break;
    default: 
//То, что будет, если ни одно вышестоящие условие не выполнено
    
echo 'А страница-то пустая :)';
    break;


Кстате, вы можете грузить одну и туже страницу по нескольким именам:
PHP код:

switch($file){
    case 
'eto':
    case 
'tolko':
    include(
'files/eto.html');
    break;
    
//


Помните, что обрабатыватся должны абсолютно все данные участвующие в сценарии. Будь то файл cookie, в котром хранятся данные о папке языка, будь то название шаблона.

Readfile or include?
Если в файле не планируется исполнения кода, то можно пользоватся функцией file_get_contents или readfile.

Например:
PHP код:

echo file_get_contents('files/'.$file.'html');
//or
readfile('files/'.$file.'.html'); 

Это также обезапасит вас, если вы создаете файлы динамически из админ-центра.
Ведь если злоумышленик получит доступ в админ-панель, а там создаст страницу с плохим кодом, то для вас это будет не менее печально, чем если бы был инклудинг файлов.

blaga 25.03.2007 16:24

Неплохо вроде...) Насчет SQL-Injections неплохо написал nerezus вот здесь https://forum.antichat.ru/thread30641.html там целая тема по тому же способу что ты описал...
Рекомендую к прочтению как в добавку к этой статье.

Isis 25.03.2007 16:26

Так все хорошо, но начало....(Защита от sql-inj) я бы поправил....
Правильней было бы сделать так:
PHP код:

   if (!get_magic_quotes_gpc()) {
   
$id mysql_escape_string($_REQUEST['id']);  
   } else {
   
$id $_REQUEST['id']
   } 

Это сделано для правильного вывода защиты....т.е. если у нас есть магия, а мы все равно делаем mysql_escape_string, то вывод будет не 1 кавычкой, а четыремя....вот и код не красивый получился бы :)

А так молодец....+ 3

GreenBear 25.03.2007 18:24

я просто стараюсь держаться подальше от блядских серверов, чего и всем советую

nerezus 25.03.2007 18:29

Цитата:

get_magic_quotes_gpc
предпочтительно поковырятться в конфиге сервера и отключить эту пакость.
Радует, что ее не будет в PHP6.


Время: 07:04