ЭФФЕКТИВНОСТЬ ИСПОЛЬЗОВАНИЯ ВСТРОЕННОЙ ФУНКЦИИ PHP ДЛЯ ЗАЩИТЫ ОТ XSS
© Сторчак С.А.*
Открытое акционерное общество «Акционерный городской банк «Таганрогбанк», г. Таганрог
В статье рассматривается способность встроенной функции «html-specialchars» языка PHP противостоять межсайтовому выполнению сценариев.
Ключевые слова информационная безопасность, уязвимость, меж-сайтовое выполнение сценариев.
PHP - интерпретируемый скриптовый язык программирования, выполнение программы (скрипта) осуществляется интерпретатором без этапа компиляции. Основной целью PHP является предоставление веб-разработчикам возможности быстрого создания динамически генерируемых веб-страниц: PHP-скрипты выполняются на сервере и генерируют HTML-страницу, которая отправляется клиенту. Клиент получает только результат выполнения кода, расположенного на сервере, но не может выяснить, какой именно код его произвел [1]. Таким образом, исходя из назначения, основной функционал языка PHP направлен на обработку текстовых строк, составляющих HTTP-запросы и HTTP-ответы (HTML-страницы).
PHP используется многими разработчиками и находится на 6 месте по популярности среди языков программирования [2] и на 1 месте по использованию данного языка для разработки веб-приложений [3]. Использование PHP и количество расширений для него продолжает расти. Сам язык тоже развивается, его всё больше применяют вне области веб-разработки, используют в качестве языка сценариев общего назначения и встраиваемого языка. Поддержку PHP включают в некоторые проекты с открытым исходным кодом. Кроме того, активно развиваются облачные сервисы и появляются новые услуги, в частности, «программное обеспечение как услуга» (Software-as-a-Service, SaaS), где также применяется рассматриваемый язык программирования.
В связи с тем, что PHP не был изначально задуман как полноценный язык программирования, а постепенно вырос из шаблонизатора для языка Perl, в нём отсутствует ортогональность. Код, созданный для более ранних версий языка, зачастую не работает или работает некорректно с более поздними версиями языка [4]. В более поздних версиях исключаются конструкции, методики, функции, применявшиеся ранее, поэтому приложения, созданные несколько лет назад, практически теряют работоспособность для современных
* Специалист по обеспечению информационной безопасности.
версий языка и требуют значительной модификации. Такие изменения обусловлены двумя факторами: устранением несогласованного синтаксиса и устранением конструкций, поощряющих создание небезопасного кода.
Уязвимости PHP обусловлены как недочётами языка, так и ошибками реализации. По данным статистики «CVE Details» в период с 1999 по 2014 гг. в PHP было обнаружено 351 уязвимостей различного типа и выпущено 82 исправления безопасности [5]. На февраль 2014 г. открытыми остаются 22 ошибки безопасности [6].
Уязвимости, приводящие к атакам на веб-приложения, можно разделить на два типа: уязвимости на стороне сервера и уязвимости на стороне клиента. К последнему относится межсайтовое выполнение сценария (Cross Site Sсriрting, XSS) - распространенный тип атаки, заключающийся во внедрении вредоносного кода (который будет выполнен на компьютере пользователя при открытии им этой страницы) в выдаваемую веб-сервером страницу и взаимодействии этого кода с веб-сервером злоумышленника. Данная уязвимость возникает при недостаточной фильтрации данных, полученных от пользователя, при условии, что эти данные выводятся в браузер. XSS-уязви-мость может привести к подмене главной страницы сайта на другую, перенаправлению пользователя на зараженный ресурс, вставке вредоносного кода, краже COOKIE-файлов, сессии и другой конфиденциальной информации, хранящейся в браузере и используемой на уязвимом сайте.
Один из способов, который применяется для борьбы с межсайтовым выполнением сценариев, является экранирование выходных данных, в частности, с использованием встроенной PHP-функции «htmlspecialchars». Основное предназначение этой функции - преобразование в escape-последова-тельности символов "&" (амперсанд), """ (двойная кавычка), "'" (одиночная кавычка), "<" (знак "меньше чем") и ">" (знак "больше чем"). Она полезна при отображении данных, введенных пользователем, которые могут содержать нежелательные HTML-теги, например, на форуме, в гостевой книге, на онлайн-доске объявлений, т.е. там, где постоянно могут храниться сообщения пользователей.
Описание функции выглядит следующим образом:
string htmlspecialchars (string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = 'UTF8' [, bool $double_encode = true ]]])
Если проанализировать этапы развития данной функции, можно заметить, что добавлению нового параметра или установке определенного значения по умолчанию в том или ином параметре поспособствовали найденные ошибки безопасности / уязвимости в рассматриваемой функции.
Для противодействия XSS-атакам использовать функцию «htmlspecial-chars» без параметров или со значениями по умолчанию недостаточно, для
этого необходимо указывать как минимум два обязательных параметра: $string и $flags со значением ENT_QUOTES.
Ниже приведён исходный код HTML-страницы, демонстрирующий проведение XSS-атаки при значениях, установленных по умолчанию [7].
<!DOCTYPE html> <?php
$input = <<<INPUT' onmouseover='alert(/XSS/); INPUT;
/*Примечание: это эквивалентно htmlspecialchars($input, ENT_COMPAT)*/
$output = htmlspecialchars($input); ?>
<html>
<head>
<title>Использование значения ENT_COMPAT</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<span title='<?php echo $output ?>'> Наведите на текст мышкой<^рап>
</div>
</body>
</html>
Если запустить данную страницу в браузере и навести указатель мыши на текст, переменной $input присвоится значение «alert(/XSS/)». Т.к. флаг со значением ENT_COMPAT не преобразует одинарные кавычки, это приведет к XSS-атаке (о чем свидетельствует появившееся всплывающее окно с текстом «/XSS/»).
Рассмотрим другой пример, в котором вообще не используются кавычки:
<!DOCTYPE html> <?php
$input = <<<INPUT faketitle onmouseover=alert(/XSS/); INPUT;
$output = htmlspecialchars($input, ENT_QUOTES);
?>
<html> <head>
<title>Использование параметра ENT_QUOTES</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<span title=<?php echo $output ?>>Наведите на текст мышкой</span>
</div>
</body>
</html>
Этот пример показывает, что все значения HTML-атрибутов должны заключаться в кавычки (желательно, в двойные), в любом сценарии, где есть подозрение на ввод ненадежных данных в значение этого атрибута или в то место, где в функции «htmlspecialchars» не установлен флаг со значением ENT_QUOTES.
Представленные примеры показывают недостаточную эффективность защиты от межсайтового выполнения сценариев при использовании «функции безопасности» PHP, которая тоже имеет уязвимости. Сомнительно, что в ближайшее время в PHP появится 100 % защита против XSS-атак. Лучшие практики по созданию безопасных веб-приложений помогут защититься от подобного рода атак. Они содержать следующие рекомендации [8-11]:
- Используйте экранирование выходных данных. Используйте экранирование выходных данных. Применяйте встроенные функции для очистки кода от вредоносных скриптов. К ним относятся такие функции как htmlspecialchar(), htmlentities() и strip_tags(). Встроенные функции PHP, в отличие от самописных, работают гораздо быстрее, а также имеют меньше ошибок безопасности и уязвимостей, т.к. постоянно совершенствуются. Также рекомендуется использовать специальные библиотеки, построенные на основе встроенных функций и фильтров. В качестве примера можно привести OWASP Enterprise Security API (ESAPI), HTML Purifier, Reform, ModSecurity.
- Используйте подход «белые списки». Подход работает по принципу «что не разрешено, то запрещено». Это стандартный механизм валидации полей для проверки всех входных данных, включая заголовки, куки, строки запросов, скрытые поля, а также длину полей форм, их тип, синтаксис, допустимые символы и другие правила, прежде чем принять данные, которые будут сохраненные и отображены на сайте. К сожалению, со своей задачей встроенные фильтры валидации данных PHP не справляются, поэтому рекомендуется писать собственные фильтры и дорабатывать их по мере необходимости. Таким образом, со временем ваши входные методы фильтрации будут усовершенствованы. Стоит также не забывать, что существует слишком много типов активного содержимого и способов кодирования для обхода подобных фильтров. По этой же причине не используйте проверку по «черному списку».
- Указывайте кодировку на каждой веб-странице. Для каждой вебстраницы необходимо указывать кодировку (например, ISO-8859-1 или UTF-8) до каких-либо пользовательских полей. Если в http-за-головке или в метатегах кодировка не указана, браузер пытается сам определить кодировку страницы. Стандарт HTML 5 не рекомендует использовать такие кодировки, которые включают JIS_C6226-1983, JIS_X0212-1990, HZ-GB-2312, JOHAB (Windows code page
1361), а также кодировки, основанные на ISO-2022 и EBCDIC. Кроме того, веб-разработчики не должны использовать CESU-8, UTF-7, BOCU-1 и кодировки SCSU. Эти кодировки никогда не предназначались для использования для веб-контента [12].
- Установите флаг HttpOnly. Этот флаг делает клиентские куки недоступными через языки сценариев, такие как JavaScript.
- Используйте Content Security Policy (CSP). Это заголовок, который позволяет в явном виде объявить «белый список» источников, с которых можно подгружать различные данные, например, JS, CSS, изображения и пр. Даже если злоумышленнику удастся внедрить скрипт в веб-страницу, он не выполниться, если не будет соответствовать разрешенному списку источников.
- Регулярно проводите анализ безопасности кода и тестирование на проникновение. Используйте как ручной, так и автоматизированный подходы. Такие инструменты как Nessus, Nikto и OWASP Zed Attack Proxy помогут обнаружить уязвимости XSS в вашем веб-приложении.
- Пользователям рекомендуется регулярно обновлять браузер до новой версии и использовать для них расширения, например, No-Script.
Список литературы:
1. Руководство по PHP. Что такое PHP? [Электронный ресурс]. - Режим доступа: http://www.php.net/manual/ru/intro-whatis.php.
2. TIOBE Index for February 2014 [Электронный ресурс]. - Режим доступа: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html.
3. W3Techs. Usage Statistics and Market Share of Server-side Programming Languages for Websites, February 2014 [Электронный ресурс]. - Режим доступа: http://w3techs.com/technologies/overview/programming_language/all.
4. Руководство по PHP. Переход с PHP 4 на PHP 5.0.x [Электронный ресурс]. - Режим доступа: http://us2.php.net/manual/ru/migration5.incompatib-le.php.
5. CVE Details. Vulnerability Statistics [Электронный ресурс]. - Режим доступа: http://www.cvedetails.com/product/128/PHP-PHP.html?vendor_id=74.
6. PHP. Bugs Stats [Электронный ресурс]. - Режим доступа: https://bugs. php.net/stats.php?bug_type=Security.
7. A Hitchhiker's Guide to Cross-Site Scripting (XSS) in PHP (Part 1): How Not To Use Htmlspecialchars() For Output Escaping [Электронный ресурс]. -Режим доступа: http://blog.astrumfutura.com/2012/03/a-hitchhikers-guide-to-cross-site-scripting-xss-in-php-part-1-how-not-to-use-htmlspecialchars-for-out-put-escaping/#codesyntax_ 1.
8. PHP Security Guide [Электронный ресурс]. - Режим доступа: http://phpsec.org/projects/guide.
9. CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') [Электронный ресурс]. - Режим доступа: http://cwe. mitre.org/data/definitions/79.html.
10. OWASP Top 10 2013-A3-Cross-Site Scripting (XSS) [Электронный ресурс]. - Режим доступа: https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_%28XSS%29.
11. OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet [Электронный ресурс]. - Режим доступа: https://www.owasp.org/index.php/XSS_%28 Cross_Site_Scripting%29_Prevention_Cheat_Sheet.
12. HTML Standart. The elements of HTML [Электронный ресурс]. - Режим доступа: http://www.whatwg.org/specs/web-apps/current-work/multipage/ semantics.html#charset.