| « Displaying Chinese UTF-8 characters in gvim on Windows | Prosper's insecure bank account management feature » |
$_SERVER['PHP_SELF'] and cross-site scripting
Monday, May 20, 2013
It's tempting to assume that PHP's $_SERVER array mostly contains fields out of the reach of an attacker, since these are "server" variables. However, that's not always the case; in particular, the seemingly innocuous PHP_SELF field can be a vector for cross-site scripting.
For example, consider the following foo.php:
<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<!-- ...form elements... -->
</form>
If I visit http://www.example.com/foo.php, $_SERVER['PHP_SELF'] will be /foo.php and everything will work correctly.
But what if I visit http://www.example.com/foo.php/"><script>alert('hello');</script> instead? Then the rendered HTML will be:
<form method="POST" action="/foo.php/"><script>alert('hello');</script>">
<!-- ...form elements... -->
</form>
This allows injection of arbitrary script running under the host site's context, also known as XSS. Two ways to fix this are:
- Use
$_SERVER['SCRIPT_NAME']instead of$_SERVER['PHP_SELF']. The former is the name of the actual script file and can't normally be manipulated by an attacker. - Use htmlspecialchars(), which by default will escape double-quotes and prevent a user-supplied string from breaking out of an HTML attribute context.
By the way, this was pretty surprising behavior to me for two reasons:
- The documentation of PHP_SELF is misleading: The first sentence says:
It seems odd that PHP would refer to something likeThe filename of the currently executing script, relative to the document root.
/foo.php/"><script>alert('hello');</script>as a "filename." - It's pretty bizarre default behavior that PHP will execute
/foo.phpfor a request of/foo.php/bar/baz.
Comments
jojifixKah on Tuesday, September 1, 2026 at 23:41
Для маркетинга и аналитики бизнеса мобильные прокси превратились в реальный рабочий инструмент. С их помощью команда проверяет, как реально открываются рекламные сценарии, лендинги и формы на мобильных устройствах. Заказать надежные мобильные прокси удобно на сайте <a href=https://lte-center.ru/>https://lte-center.ru/</a> — сервис помогает анализировать региональную среду и собирать открытые рыночные данные. Достоверная картина убирает домыслы и делает каждое решение более прибыльным.
yupmjug on Wednesday, September 2, 2026 at 00:44
Градуировка емкостей — необходимая метрологическая операция, выявляющая зависимость объема резервуара от уровня жидкости в нем. Точность градуировочной таблицы напрямую влияет на учет нефтепродуктов и других жидкостей. Ищете <a href=https://rascet.ru/>геометрический метод градуировки</a>? Быстро составить таблицу поможет программа RASCET на сайте rascet.ru проверенная на промышленных объектах с 2002 года. Алгоритмы аппроксимации гарантируют высокую точность расчетов геометрическим методом.
wicotlphhom on Wednesday, September 2, 2026 at 01:13
Travelpayouts — это партнёрская платформа для тех, кто ведёт блог или сайт о путешествиях и хочет монетизировать свой контент. Сервис позволяет размещать партнёрские ссылки, виджеты и баннеры без навыков программирования и даже без ожидания верификации аккаунта. Удобная статистика показывает клики и бронирования, помогая отслеживать эффективность. Подробнее о возможностях можно узнать на сайте <a href=https://clck.ru/3CRSp6>https://clck.ru/3CRSp6</a> — там же доступен блог с советами по созданию контента, повышению конверсий и заработку в соцсетях. Служба поддержки оперативно отвечает на вопросы, что делает старт максимально простым и комфортным даже для новичков.
DanielKeype on Wednesday, September 2, 2026 at 01:30
Roam Like at Home applies to the 27 EU member states plus Iceland <a href="https://gist.github.com/foulegold/4cc47a79039409c1645cadcecc44a245">https://gist.github.com/foulegold/4cc47a79039409c1645cadcecc44a245</a>
David Annis on Wednesday, June 25, 2014 at 06:32
I have used the fact that php will execute /foo.php from a request that contains /foo.php/bar to make search engine friendly URLs because many search engines will not index both wheretodrink.php?answer=bar and wheretodrink.php?answer=home because they fear an infinite set of URLs.