【问题标题】:Risk of using $_SERVER['REQUEST_URI'] or $_SERVER['PHP_SELF'] in forms and links在表单和链接中使用 $_SERVER['REQUEST_URI'] 或 $_SERVER['PHP_SELF'] 的风险
【发布时间】:2013-01-29 14:43:54
【问题描述】:

$_SERVER['REQUEST_URI']$_SERVER['PHP_SELF'] 用作表单中的操作或链接中的href 是否有风险?

如果是这样,可以做些什么来减轻风险?

【问题讨论】:

    标签: php


    【解决方案1】:

    我意识到这是一篇相当老的帖子,但我前段时间也遇到过这个问题。我现在做的是这样的:

    $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 变量而不必太担心。

    我希望这可以帮助那些徘徊在此线程上寻找答案的人。

    【讨论】:

    • 为这个旧问题添加了出色的新方法
    【解决方案2】:

    您在 www.example.com/form.php 上制作表格。一年后,您会忘记 URL 只是抓取页面加载的任何 URL。

    假设您在框架中添加了一个“删除所有内容”全局选项,作为完全不同(有点奇怪)请求的一部分。

    现在,有人向您发送此链接:www.example.com/form.php?delete_everything=true。由于您只是获取该 URL 并将其设置为操作,因此这就是您表单上的操作。哎呀。 XSS 攻击基本上就是这样工作的。

    始终假设您的代码会以您第一次编写时未预料到的方式被使用(甚至是您,尤其是黑客)。

    你如何绕过它?硬编码网址!您可以包含一个返回 URL 的函数。实际上,这就是 Symfony 或 CodeIgniter 等框架解决它的方式。

    【讨论】:

    • 谢谢布洛夫斯基。硬编码的问题不是 URL,而是 URL 中的数据。例如,我的 URL 是 mysite.com?id=123 其中 123 带来了特殊数据。无法对每个 ID 进行硬编码。
    • 另外,如果用户将 www.example.com/form.php?delete_everything=true 放在他的客户端浏览器中,会不会产生同样的效果?这如何处理 XSS?
    • 对于 URL 参数,您可以执行 action="www.example.com/form.php?id=&lt;?php echo htmlspecialchars($_GET['id']); ?&gt;" 之类的操作。就delete_everything=true 而言 - 这是一个非常简单的例子(无论如何都有这样一个参数是疯狂的想法),但想象一下只有管理员可以传递该参数 - 没问题吧?但是有一天,有人向管理员发送了一封包含该参数的电子邮件,他有点着急,点击 URL,提交表单...
    • 仍然很难!当另一个客户端向服务器发出请求时,一个客户端如何影响 $_SERVER['REQUEST_URI'] 的出现?
    • 多种方式,但最常见的是社会工程。想象一下公司里有人的电子邮件被黑了。黑客使用该帐户向 IT 负责人发送一封电子邮件,内容是“请您填写此表格”,并附上指向真实网站的链接 - 但是 讨厌的参数已添加到 URL 的末尾。现在,当 IT 主管提交表单时,它会将参数传递给后端,并且损坏已完成。这里的重点是它增加了巨大的风险而收益却很少——编写一个诚实地构造 URL 的函数不会花费很长时间。
    【解决方案3】:

    这是因为$_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>
    

    解决方案

    在许多情况下,使用&lt;form action=""&gt; 足以使表单发布到脚本本身。否则,如果您知道脚本名为"bla.php",则设置action="bla.php"

    【讨论】:

    • 如何在XSS攻击中使用?我可以看到有人如何为他们的客户端 PC 更改它,但不是为其他人。你如何建议逃避它? esc_url()?
    • @user1032531 考虑在很多人访问的论坛中添加这些链接?
    • 你好,杰克。我看了你的帖子20遍了,还是没看懂。任何其他线索将不胜感激。
    • 好吧,也许我明白了。坏人向论坛添加链接或其他内容。好人点击链接,URL 包含一些被执行的 JS。仍然不清楚它与表单的关系。
    • @user1032531 不仅仅与表单有关,它还可以应用于任何具有这些变量未经审查的值的事物。
    【解决方案4】:

    $_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

    永远记得清理输入数据......永远!

    【讨论】:

    • 谢谢乔,但这不会影响访问该 URL 的客户的个人吗?它会如何影响其他人?
    • 所以这是一个愚蠢的问题,但为什么在我的所有测试中我都遇到了 403 错误并且页面甚至没有加载?
    【解决方案5】:

    不要忘记在整个脚本中将每次出现的“$_SERVER['PHP_SELF']”转换为“htmlentities($_SERVER['PHP_SELF'])”。

    如何避免 PHP_SELF 漏洞利用 http://www.html-form-guide.com/php-form/php-form-action-self.html

    【讨论】:

      【解决方案6】:

      不,因为任何人都可以更改链接的href(使用 Firebug 之类的工具)。当然,请确保不要在该链接中放置任何敏感数据。

      始终确保正确验证和解析您收到的用户数据。

      【讨论】:

      • 谢谢 Bart,表单操作也是如此,对吗?
      • 是的。 (虽然我不知道为什么我的答案被否决了......)
      • @BartFriederichs 我投了反对票。虽然任何人都可以更改 href,但如果它是硬编码的,它将始终按照开发人员的要求加载。通过获取 $_SERVER[] 变量,您将自己暴露在攻击之下。因此,这是非常危险的,应该是最后的手段。
      • @Blowski 谢谢。我得重新研究一下 XSS 攻击。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多