【问题标题】:Reflective XSS Protection - clarification?反射型 XSS 保护 - 澄清?
【发布时间】:2014-02-10 18:06:00
【问题描述】:

在阅读了 Eric Lawrence 的this article 之后,我看到了这个测试页面http://www.enhanceie.com/test/xss/,它模拟了Reflective XSS Protection 的用法。

现在,根据google chromium

XSS 过滤器检查是否有脚本即将在网页上运行 也存在于获取该网页的请求中。如果 请求中存在脚本,这强烈表明 Web 服务器可能已被欺骗以反映脚本。

所以,如果我发布到服务器:

<script>alert("bang! script injection\n"+document.cookie);</script>

并且浏览器也可以看到它通过 url 的请求:

http://webdbg.com/test/xss/Hello.asp?txtName=%3Cscript%3Ealert%28%22bang%21+script+injection%5Cn%22%2Bdocument.cookie%29%3B%3C%2Fscript%3E

然后它显示此错误(控制台):

XSS Auditor 拒绝执行脚本 'http://webdbg.com/test/xss/Hello.asp?txtName=%3Cscript%3Ealert%28%22bang%21+script+injection%5Cn%22%2Bdocument.cookie%29%3B%3C%2Fscript%3E' 因为在请求中找到了它的源代码。审计员是 启用,因为服务器既不发送“X-XSS-Protection”也不发送 'Content-Security-Policy' 标头。

但是提琴手确实告诉我页面确实让脚本运行

问题:

由于处理xss的解决方案是html Encode/decode,

我应该如何/何时将这两种解决方案结合起来?

我的意思是我可以使用 html 编码并且脚本永远不会在我的页面中运行,或者,我可以使用这个标题...?

我很困惑。

【问题讨论】:

  • 作为注释,有一些攻击利用浏览器中的 XSS 过滤器通过附加到攻击者 想要的脚本的查询字符串 sn-ps在受害者站点中运行。

标签: javascript http http-headers xss fiddler


【解决方案1】:

但提琴手确实告诉我该页面确实让脚本运行

不,它没有。 Fiddler 向您展示了服务器将脚本发送回浏览器。它完全没有告诉你浏览器对脚本做了什么。

由于处理xss的解决方案是html Encode/decode

这是一种解决方案(如果您不需要允许用户提交任何类型的 HTML,这也是最简单和最好的解决方案)。

我应该如何/何时将这两种解决方案结合起来?

您应该通过编码实体将获得的任何用户输入编码为 HTML,并忽略出现在一些浏览器中的反 XSS 过滤器,因为并非所有浏览器都有它们,因此您不能依赖它们。

我的意思是我可以使用 html 编码并且脚本永远不会在我的页面中运行

只对用户输入进行编码(因为它是不受信任的)。不要对您自己编写的脚本进行编码,因此可以信任。

【讨论】:

    【解决方案2】:

    编码和解码是XSS漏洞最可靠的解决方案。确保为正确的上下文进行编码。即,如果将受污染的数据插入到 javascript 中,则调用 javascript 编码器而不是 html 编码器。 ESAPI 有一个很好的库,包含您需要的所有编码器。

    此外,一些浏览器现在支持带有标题的内容安全策略设置,这也有助于对抗 XSS。这是一篇关于它的文章http://www.html5rocks.com/en/tutorials/security/content-security-policy/

    不要依赖浏览器过滤器,因为您无法确定您的用户是否会在他们的浏览器中使用该功能。始终清理您的数据。

    【讨论】:

      【解决方案3】:

      简单的 HTML 编码就足以防止 XSS。如果用户输入 xss 字符,它们将被编码,但字母数字字符将保持原样。

      除此之外,您可以在jsp页面中使用核心jstl库的标签。

      【讨论】:

      • 编码不是唯一的解决方案。一个更安全的环境在进入过程中进行清理(通常拒绝需要清理的请求是最安全的途径),然后对输出进行编码。
      【解决方案4】:

      最好给出例子而不是写作。

      反射型 XSS POC

      <?php
      /**
       * @Author Vaibs
       *
       */
      $cookie_name = "user";
      $cookie_value = "John Doe";
      setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
      if (isset($_REQUEST['Submit'])) { //check if form was submitted
          $input = isset($_REQUEST['appid']) ? $_REQUEST['appid'] : "";//get input text
          echo "Input from client is reflected back as ->  : " . $input;
      }
      ?>
      
      <html>
      <body>
      <form>
          <input type="text" name="appid"/>
          <input type="submit" name="Submit"/>
      </form>
      </body>
      </html>
      

      如何避免? 答:最简单的就是使用PHP函数urlencode。

      <?php
      /**
       * @Author Vaibs
       *
       */
      $cookie_name = "user";
      $cookie_value = "John Doe";
      setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
      if (isset($_REQUEST['Submit'])) { //check if form was submitted
          $input = isset($_REQUEST['appid']) ? $_REQUEST['appid'] : "";//get input text
          echo "Input from client is reflected back as ->  : " . urlencode($input);
      }
      ?>
      
      <html>
      <body>
      <form>
          <input type="text" name="appid"/>
          <input type="submit" name="Submit"/>
      </form>
      </body>
      </html>
      

      不同之处在于使用了第二个代码中使用的urlencode函数。

      【讨论】:

        猜你喜欢
        • 2021-11-02
        • 1970-01-01
        • 2014-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-23
        • 2015-10-03
        • 1970-01-01
        相关资源
        最近更新 更多