PHP_SELF и XSS инъекция

Инъекция - это может быть больно!Если вы столкнулись с кучей ошибок 404, в которых фигурировали искажённые урл, как будто туда была вставлена какая-то абракадабра, или может увидели такую ошибку:

Newline found in PHP_SELF variable which might cause possible injection '_ВАШ_URL_'

Тогда вам надо прочитать этот пост. Предупреждён — значит вооружён!

К сожалению я не нашёл информации о XSS инъекции через PHP_SELF на русском языке, поэтому тут я размещу перевод одной путёвой статьи. Итак:

$_SERVER['PHP_SELF'] and cross-site scripting
============================

Принято считать что глобальный PHP массив $_SERVER в основном содержат поля недоступные для модификации хакером, т.к. они «серверные». Однако это не всегда верно, в частности кажущееся безобидным поле PHP_SELF может стать объектом атаки

Рассмотрим пример некоего файла foo.php

Если вы просто зайдёте по ссылке вида http://www.example.com/foo.php , то $_SERVER['PHP_SELF'] будет просто /foo.php , и всё будет работать правильно.

Но что если посетить http://www.example.com/foo.php/»><script>alert(‘hello’);</script> ? Тогда наш код сгенерирует следующий HTML

">

Это позволяет выполнять произвольный скрипт в контексте вашего сайта. А это уже XSS. Два пути этого избежать:

  • Используйте $_SERVER['SCRIPT_NAME'] вместо $_SERVER['PHP_SELF']. Это даст реальное название выполняемого скрипта и не может быть подделано хакером.
  • Используйте htmlspecialchars(), это должно вырезать весь вредоносный код из сроки URI

Кстати, это довольно неожиданное поведение для меня по двум соображениям:

  • Документация по PHP_SELF вводит в заблуждение. Первое предложение говорит:

    Имя файла текущего исполняемого скрипта относительно корня вебсайта.

    Это кажется странным, что PHP ссылается на что-то вроде
    /foo.php/"><script>alert('hello');</script> как к «имени файла»

  • Это довольно странно, что PHP будет выполнять /foo.php для запроса /foo.php/bar/baz.

Дополнение
============================
Добавлю от себя третий путь — никогда не использовать PHP_SELF и всегда явно прописывать требуемые URL.

Ссылки
============================