【发布时间】:2013-01-29 14:43:54
【问题描述】:
将$_SERVER['REQUEST_URI'] 或$_SERVER['PHP_SELF'] 用作表单中的操作或链接中的href 是否有风险?
如果是这样,可以做些什么来减轻风险?
【问题讨论】:
标签: php
将$_SERVER['REQUEST_URI'] 或$_SERVER['PHP_SELF'] 用作表单中的操作或链接中的href 是否有风险?
如果是这样,可以做些什么来减轻风险?
【问题讨论】:
标签: php
我意识到这是一篇相当老的帖子,但我前段时间也遇到过这个问题。我现在做的是这样的:
$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 变量而不必太担心。
我希望这可以帮助那些徘徊在此线程上寻找答案的人。
【讨论】:
您在 www.example.com/form.php 上制作表格。一年后,您会忘记 URL 只是抓取页面加载的任何 URL。
假设您在框架中添加了一个“删除所有内容”全局选项,作为完全不同(有点奇怪)请求的一部分。
现在,有人向您发送此链接:www.example.com/form.php?delete_everything=true。由于您只是获取该 URL 并将其设置为操作,因此这就是您表单上的操作。哎呀。 XSS 攻击基本上就是这样工作的。
始终假设您的代码会以您第一次编写时未预料到的方式被使用(甚至是您,尤其是黑客)。
你如何绕过它?硬编码网址!您可以包含一个返回 URL 的函数。实际上,这就是 Symfony 或 CodeIgniter 等框架解决它的方式。
【讨论】:
action="www.example.com/form.php?id=<?php echo htmlspecialchars($_GET['id']); ?>" 之类的操作。就delete_everything=true 而言 - 这是一个非常简单的例子(无论如何都有这样一个参数是疯狂的想法),但想象一下只有管理员可以传递该参数 - 没问题吧?但是有一天,有人向管理员发送了一封包含该参数的电子邮件,他有点着急,点击 URL,提交表单...
这是因为$_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",则设置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
永远记得清理输入数据......永远!
【讨论】:
不要忘记在整个脚本中将每次出现的“$_SERVER['PHP_SELF']”转换为“htmlentities($_SERVER['PHP_SELF'])”。
如何避免 PHP_SELF 漏洞利用 http://www.html-form-guide.com/php-form/php-form-action-self.html
【讨论】:
不,因为任何人都可以更改链接的href(使用 Firebug 之类的工具)。当然,请确保不要在该链接中放置任何敏感数据。
始终确保正确验证和解析您收到的用户数据。
【讨论】: