Все мы знаем что Flash!-анимация и PNG-изображения давно плотно засели
в web-проекты. Если Вы пишите свой собственный форум или нечто подобное
то Вам не обойтись без аватар, это уже как стандарт. Но если недавно
самой распространённой опасностью была загрузка PHP-скриптов через
аватары, то сейчас на её место пришли картинки и Flash!-анимации
несущие в себе вредоносный код. Фильтрации поступающего контента
сейчас разработчики уделяют много внимания, и никаких скриптов через
аватару не загрузишь, но те же разработчики в упор не хотят понимать
опасность как XSS так и изображений/анимаций несущих в себе вредоносный
код.
Вы можете сказать что используйте htmlspecialchars() и ей подобные
функции во всех местах где можно. Это хорошо. А фильтруете ли Вы
изображения и Flash!-анимации поступающие к Вам на сайт? думаю 95%
читателей ответят что нет. Как мне кажется причины 2:
- Незнание как производить эту самую фильтрацию
- Отношение к XSS как к «детской» атаке( Если Вы желаете узнать
что можно сделать с помощью XSS то можете прочитать мою статью на
данную тему [1].).
- Незнание того что атака через картинки и анимации возможна.
Ниже я рассмотрю способы безопасного использования картинок и анимаций
поступающих от пользователей. Ещё хотелось бы заметить отдельно что
вариант «запретить загрузку таких файлов» - это ни в коем случае не
решение проблемы, так как цель любого программиста сделать проект
максимально гибким и при этом максимально безопасным. А запрет загрузки
PNG/SWF-файлов это безопасность в обмен на гибкость. Подобные решения
принимаются только тогда когда надежды действительно нет, и бывает это
очень редко.
Защита от XSS-атак по средствам Flash!-анимации.
Многие форумы (например IPB) позволяют загружать Flash!-анимации
посетителям. Но в том же IPB написано что разрешать такие загрузки не
желательно так как они могут повлиять на безопасность форума. А именно
– через Flash!-анимацию можно провести XSS-нападение. Данная подпись
почему то мало волнует администраторов и они разрешают загрузку Flash!.
Если же Ваш сайт с загрузкой Flash! никак не связан то всё равно
советую прочитать то что описано ниже. Лишним никогда не будет. Итак.
Для начала давайте посмотрим как происходит само нападение. Например
Flash!-ролик содержит следующий ActionScript-код:
getURL("javascript:alert('XSS')");
Тогда при просмотре страницы с этим роликом пользователь увидит следующее сообщение:
заметьте что это произвольный JS-код. А кто мешает взломщику
использовать например innerHTML что бы изменить контент текущей
страницы? Что бы защититься от этого Macromedia предлагает 2 варианта[2]:
Первое решение заключается в том что бы хранить загруженные ролики на
отдельном хосте с отдельным доменным именем и размещать их на странице
через тег iframe. В сообщении компании Macromedia говорится что такой
вариант хорош тем что Flash!-ролик будет иметь доступ к телу iframe
через который он загрузился. То есть имеется в виду что он будет
находится как бы в песочнице, из которой на главный сайт он не как не
выберется. Это не очень удобно так как есть браузеры не поддерживающие
этот тэг, либо тэг может блокироваться файрволом (например Outpost
Firewall).
Второй вариант просто идеален - использовать опцию AllowScriptAccess
которую ввели во Flash-player ещё в 2002 году. Данная опция отвечает за
выполнение запросов функции getURL. Если она установлена в 'never' то
getURL не сможет выполнится. Вот пример использования данной опции в
теге EMBED:
<EMBED AllowScriptAccess='never' src="1.swf" WIDTH=468 HEIGHT=60 TYPE="application/x-shockwave-flash"></EMBED>
Если в файле 1.swf содержится код вызывающий getURL то он просто не
выполнится, причём на работу самого ролика и остального
ActionScript-кода это не повлияет.
Обратите внимание на то что если не установить значение этой опции то
оно автоматически будет приравнено к значению always, а значение always
опции AllowScriptAccess разрешает вызов getURL. Вот и вариант защиты –
добавлять опцию AllowScriptAccess.
Далее давайте обсудим защиты от атак с помощью PNG-картинок.
Защиты от атак с помощью PNG-картинок.
Хоть это и кажется бредом но это возможно. Делается это простым
дописыванием html-кода в конец PNG-файла. В итоге браузер выплёвывает
текстовое содержимое файла наружу и код выполняется. Неудобств у этой
атаки 3:
- Атакуемый должен обратится непосредственно к картинке, а не к страничке её содержащую. Например www.server.com/image1.png.
- Многие популярные движки хранят расширение файлов в базе, а
сами файлы лежат переименованные в отдельной папке с одним и тем же
расширением (например '.ext').
- Такие атаки проходят только с браузером Internet Explorer. Тот -же FireFox просто пишет что изображение повреждено.
Как видите ограничения хоть и есть, но они не слишком
значительны(кроме второго). Теперь разберём всё на практике. Давайте
напишем небольшой скрипт который будет отвечать за аплоад картинок на
сервер и форму в которой пользователь будет выбирать какую картинку
загрузить. Файл index.html:
<form enctype="multipart/form-data" action="upload.php" method="post"> Отправить этот файл: <input name="userfile" type="file" /> <input type="submit" value="Send File" /> </form>
и скрипт upload.php:
// Изображения сохраняем в папку images $upload_dir = "images/"; $upload_file = $upload_dir . basename($_FILES['userfile']['name']); move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_file); ?>
У нас есть самый простой аплоадер картинок. Теперь нарисуйте в любом
редакторе картинку (например точку) и сохраните. Далее откройте эту
картинку простым текстовым редактором (я использовал Bred3_2k – подобие
блокнота) и допишите в конец текст
<script>alert(1)</script>. Если всё нормально то
обратившись к этому изображению с помощью IE Вы увидите окошко с цифрой
1 и кишки картинки в виде обычного набора странных символов. Теперь
нужно поставить фильтр на этот аплоад что бы он не пропускал опасные
картинки. Давайте сделаем это на примере тега '<script>'. Мы
будем действовать следующим образом:
Сохраним загруженное изображение
Откроем как текстовый файл и возьмём внутренности
В получившемся тексте будем искать <script . Если данное выражение найдётся то удалим файл и сообщим об этом.
Вот код который нужно добавить в аплоадер после загрузки файла:
// Открываем файл для чтения $handle = fopen($upload_file, "r"); // Читаем весь полностью $file_text = fread($handle,filesize($upload_file));
fclose($handle); // Если обнаружился <script if (strpos($file_text,'<script')>-1) { // то удаляем этот файл и сообщаем пользователю unlink($upload_file); print 'XSS image!';
}
Теперь создайте ещё одно изображение только полностью безопасное и
попробуйте загрузить его на сервер. У меня всё прошло нормально, а вот
на загрузку опасного файла скрипт выругался. Естественно надо
фильтровать не только тег <script> но и тэги типа
<embed>,<applet> и т.д.. Так же нужно не забывать о
фильтрации полного слова javascript. А перед проверкой лучше текстовые
внутренности перевести через функцию strtolower() так как могут
попасться и <SCRIPT> и JAvAscRIpT:alert(1)
И ещё. Не вздумайте проверять изображения на наличие '<' и '<'
так как эти символы присутствуют в коде каждой картинки и каждое
PNG-изображение будет считаться опасным.
Удачи!
Источник: http://inattack.ru
|