$_SERVER['REQUEST_URI']
使用或$_SERVER['PHP_SELF']
作为表单中的操作或链接中的 href是否有任何风险?
如果是这样,可以采取什么措施来减轻风险?
$_SERVER['REQUEST_URI']
使用或$_SERVER['PHP_SELF']
作为表单中的操作或链接中的 href是否有任何风险?
如果是这样,可以采取什么措施来减轻风险?
您在 www.example.com/form.php 上制作表格。一年后,您会忘记 URL 只是抓取页面加载的任何 URL。
在某个时候,假设您在框架中添加了一个“删除所有内容”全局选项,作为完全不同(有点奇怪)请求的一部分。
现在,有人给你发了这个链接:www.example.com/form.php?delete_everything=true。由于您只是获取该 URL 并将其设置为操作,因此这就是您的表单上的操作。哎呀。XSS 攻击基本上以这种方式工作。
始终假设您的代码将被使用(甚至是您,尤其是黑客)以您第一次编写它时没有预料到的方式使用。
你如何绕过它?硬编码网址!您可以包含一个返回 URL 的函数。实际上,这就是 Symfony 或 CodeIgniter 等框架解决它的方式。
这是因为$_SERVER['PHP_SELF']
并且$_SERVER['REQUEST_URI']
可以通过某种方式进行操作,如果您没有正确地转义它,它可以用于 XSS 攻击。
这很大程度上是因为这样的 URL 可以正常工作:
/path/to/index.php/" onmouseover="alert('hi')
让我们使用这段代码:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>">
...
</form>
它调用/path/to/index.php
, 即SCRIPT_NAME
, 但是当你只是回显$_SERVER['PHP_SELF']
它会破坏你想要的 HTML。
<form action="/path/to/index.php/" onmouseover="alert('hi')">
...
</form>
解决方案
在许多情况下,使用<form action="">
足以使表单发布到脚本本身。否则,如果你知道脚本被调用"bla.php"
,那么 set action="bla.php"
。
$_SERVER 容易受到 XSS 攻击,应在使用前使用 htmlspecialchars() 进行清理。
一个示例注入:
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"></form>
现在使用以下注入调用表单:
http://www.example.com/form.php/%22%3E%3Cscript%3Ealert ('xss 攻击')%3C/script%3E%3Cbr%20class=%22irrelevant
永远记得清理输入数据......永远!
我意识到这是一个相当老的帖子,但这是我前段时间也遇到过的一个问题。我现在做的是这样的:
$php_self = filter_input(INPUT_SERVER, 'PHP_SELF', 522);
define('PHP_SELF', $php_self);
有了这个,您可以安全地使用常量 PHP_SELF 作为表单操作。这段代码所做的是$_SERVER['PHP_SELF']
通过过滤器运行超级全局,同时将结果分配为变量$php_self
。ID 号 522 指的是FILTER_SANITIZE_FULL_SPECIAL_CHARS
它消除了某人注入 javascript 等的能力。
您可以在此处查看这段代码可以使用哪些过滤器:
<table>
<tr><td>Filter Name</td><td>Filter ID</td></tr>
<?php
foreach(filter_list() as $id =>$filter)
{
echo '<tr><td>'.$filter.'</td><td>'.filter_id($filter).'</td></tr>'."n";
}
?>
</table>
相同的原则可以应用于大多数(如果不是全部)超级全局$_SERVER
变量。
以下是我最喜欢玩的一些:
# FILTER_SANITIZE_STRING or _STRIPPED
$server_http_xrw = filter_input(INPUT_SERVER, 'HTTP_X_REQUESTED_WITH', 513);
# FULL_SPECIAL_CHARS
$server_request_method = filter_input(INPUT_SERVER, 'REQUEST_METHOD', 522);
$http_encoding = filter_input(INPUT_SERVER, 'HTTP_ACCEPT_ENCODING', 522);
所以,无论如何,通过使用 PHP 的(现在)内置过滤器,我们可以使用$_SERVER
变量而不用担心太多。
我希望这可以帮助那些徘徊在这个线程上寻找答案的人。
不要忘记在整个脚本中将每次出现的“$_SERVER['PHP_SELF']”转换为“htmlentities($_SERVER['PHP_SELF'])”。
如何避免 PHP_SELF 漏洞利用 http://www.html-form-guide.com/php-form/php-form-action-self.html
不,因为任何人都可以更改href
链接(使用 Firebug 之类的工具)。当然,请确保您没有在该链接中放置任何敏感数据。
始终确保正确验证和解析您收到的用户数据。