- Атакуемый должен обратится непосредственно к картинке, а не к страничке её содержащую. Например www.server.com/image1.png.
- Многие популярные движки хранят расширение файлов в базе, а сами файлы лежат переименованные в отдельной папке с одним и тем же расширением (например '.ext').
- Такие атаки проходят только с браузером Internet Explorer. Тот -же FireFox просто пишет что изображение повреждено.
index.html:
upload.php:<form enctype="multipart/form-data" action="upload.php" method="post">
Отправить этот файл: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
У нас есть самый простой аплоадер картинок. Теперь нарисуйте в любом редакторе картинку (например точку) и сохраните. Далее откройте эту картинку простым текстовым редактором и допишите в конец текст <script>alert(1)</script>. Если всё нормально то обратившись к этому изображению с помощью IE Вы увидите окошко с цифрой 1 и кишки картинки в виде обычного набора странных символов. Теперь нужно поставить фильтр на этот аплоад что бы он не пропускал опасные картинки. Давайте сделаем это на примере тега ''. Мы будем действовать следующим образом:<?php
// Изображения сохраняем в папку images
$upload_dir = "images/";
$upload_file = $upload_dir . basename($_FILES['userfile']['name']);
move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_file);
?>
- Сохраним загруженное изображение
- Откроем как текстовый файл и возьмём внутренности
- В получившемся тексте будем искать <script
- Если данное выражение найдётся то удалим файл и сообщим об этом.
Теперь создайте ещё одно изображение только полностью безопасное и попробуйте загрузить его на сервер. У меня всё прошло нормально, а вот на загрузку опасного файла скрипт выругался. Естественно надо фильтровать не только тег но и тэги типа <embed>,<applet> и т.д.. Так же нужно не забывать о фильтрации полного слова javascript. А перед проверкой лучше текстовые внутренности перевести через функцию strtolower() так как могут попасться и <script></script> и JAvAscRIpT:alert(1)// Открываем файл для чтения
$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!';
}
И ещё. Не вздумайте проверять изображения на наличие '<' и '>' так как эти символы присутствуют в коде каждой картинки и каждое PNG-изображение будет считаться опасным. Удачи!