【问题标题】:Prevent auto clicked link XSS attack using CSP使用 CSP 防止自动点击链接 XSS 攻击
【发布时间】:2015-04-20 15:50:35
【问题描述】:

虽然将 CSP 用于稍微不同的目的(沙盒),但我意识到一个非常简单的自动点击链接似乎绕过了相对严格的 CSP。我所描述的内容如下:

内容安全政策:

default-src 'none'; script-src 'unsafe-inline';

还有身体:

<a href="http://www.google.com">test</a>
<script>
  document.querySelector("a").click();
</script>

显然,在真正的攻击中,您会首先将 cookie 信息包含到 href 字段中,并可能将其包装在一个隐藏的自嵌入 iframe 中,或者使域将您重定向回您的来源(可能带有额外的 url 参数因此创建了一种绕过connect-src的XMLHttpRequest),但这个基本示例确实显示了问题。

有什么方法可以通过 CSP 来防止这种情况(它仍然允许执行 Javascript)?


类似的攻击

同样的事情显然也可以用其他一些导航方法来完成。我之所以专门询问这种方法,实际上与我的次要目标有关,而不是 XSS 漏洞利用。无论哪种方式,都可以接受任何和所有真正的解决方案。

无关的侧面说明

由于所有的混乱,即使没有script-src: 'unsafe-inline',这仍然适用。想象一下以下名为api.ext的文件

print URLParameters.method
[...]

然后可以像api.ext?method=&lt;script src='api.ext?method=alert("test")//'&gt;&lt;/script&gt;&lt;!-- 一样调用此文件(除非您需要额外的 URL 编码和其他东西,这只是为了说明问题)。发现这样的漏洞很困难,而且很少见,但即使在这些情况下,似乎也存在像 connect-src 这样的东西来防止信息泄露。

【问题讨论】:

  • 您可能希望将鼠标悬停在 csp 标签上。TLA(三个字母的首字母缩写词)太多了,而您选择了错误的...
  • 没有unsafe-inline怎么办?
  • @levi 如果你有一个 XSS 漏洞,你可以控制第一个字符的全部内容(很少见,但不是看不见),你可以简单地将自己嵌入到外部嵌入中,并将你的 javascript 放在内部嵌入。但无论哪种方式,这只是一个旁注,connect-src 的存在表明 CSP 也关心 Javascript 评估 XSS 漏洞。
  • @MarcB 啊,我的错,我粗心,在我的另一篇文章中正确理解了它,不知道为什么我误写了这篇文章。
  • @JacobBundgaard 如果您已经阅读了整个问题或 cmets,您会看到 1) 即使没有 unsafe-inline,攻击仍然可以执行,并且 2) CSP 关注以下攻击由connect-src 的存在证明。

标签: javascript xss content-security-policy


【解决方案1】:

这不太可能是一种令人满意的方法 - 显然它不是基于 CSP - 但如果您真的必须防止此类攻击,它可能是您唯一的选择。在使用这样的东西之前,请确保确实没有办法禁用内联脚本(应该涵盖大多数攻击)。此外,您应该将您的反馈发送到 public-webappsec@w3.org 邮件列表,主题为 [CSP2]。

这是我的(不完整的)想法:

function guardMethods(clazz, methodNames, urlGetter, allowFilter, reportViolation) {
    var prototype = clazz.prototype;
    methodNames.forEach(function (methodName) {
        var originalMethod = prototype[methodName];
        if (originalMethod) {
            Object.defineProperty(prototype, methodName, {
                value: function () {
                    var url = urlGetter.apply(this, arguments) || '';
                    if (allowFilter(url)) {
                        return originalMethod.apply(this, arguments);
                    } else {
                        reportViolation(url);
                    }
                }
            });
        }
    })      
}

function allowFilter(url) {
    // todo: implement
}

function reportViolation(url) {
    console.error('Redirection prevented:', url);
}

guardMethods(HTMLAnchorElement, ['click', 'dispatchEvent', 'fireEvent'], function () {return this.href}, allowFilter, reportViolation);

您必须对 location、location.href、window.open 和其他允许重定向到其他页面的函数/属性/事件实施类似的保护。如果你错过了一个,那么你仍然很脆弱。 CSP 本身可以涵盖表单、XHR 和大多数其他资源。据我所知,原型 hack 在一些旧版浏览器中不起作用。

再一次,我不建议使用它。您犯错误或它在某些浏览器中不起作用或将添加可用于重定向的新 API 的可能性太高了。

【讨论】:

  • 正如我在帖子中所说的那样,我实际上是在调查这个问题,因为我试图创建一个沙盒环境,这对于我的个人需求来说似乎是 Google Caja 的一个非常有趣的替代方案(我真的不需要 Google Caja 提供的所有额外的东西)。无论哪种方式,关于这个问题,我认为如果将其创建为一个独立的库,其唯一目的是阻止这类事情,这可能是一种可行的方法。我想我会在晚上剩下的时间里试图绕过这个:D。
  • 这并没有我想象的那么长。在特定元素上分派MouseEvent 仍然可以获得点击。也许可以通过修补dispatchEvent 来解决这个问题,嗯,让我们看看~
  • 直到现在还没有时间写一个合适的评论,但是修补 dispatchEvent 比这要困难得多:应该允许事件冒泡并调度其他事件。此外,您需要将HTMLAnchorElement 切换为HTMLElement
【解决方案2】:

CSP 是减少 XSS 造成的破坏的方法之一,但它绝不是修复由 XSS 漏洞引起的所有问题的魔法棒。这个非目标也在CSP specification中明确列出:

内容安全策略 (CSP) 并不是针对内容注入漏洞的第一道防线。相反,CSP 最好用作纵深防御,以减少内容注入攻击造成的危害。作为防止内容注入的第一道防线,服务器运营商应该验证他们的输入并对其输出进行编码。

如果您必须运行 JavaScript 代码,但您不能信任该代码,那么您可以使用不带 allow-same-origin 标志的沙盒指令为页面提供服务。使用此 CSP 指令,页面将在唯一的安全源上运行,该安全源不与显示的源共享任何状态(即 cookie、DOM 存储、数据库……)。因此,注入的脚本不会泄露信息,因为它们一开始就无法获取信息。

例如,要允许内联脚本运行,但不能访问同源数据,请使用:

default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts

不要像另一个答案所建议的那样将 JavaScript 方法列入黑名单,因为 1) 你总是会忽略一个方法,2) 禁用 JavaScript API 可能会以意想不到的方式破坏你的 Web 应用程序,以及 3) 攻击者只需要一个漏洞造成损害,并且您的(自定义)应用程序可能包含至少一种可能被攻击者滥用的方法。

【讨论】:

    【解决方案3】:

    内容安全政策是为了页面本身的安全。导航到另一个页面不是绕过或涉及 CSP 的事情。 CSP 只关心您的页面及其功能。这也不是限制最终用户使用浏览器的实用程序(例如安装插件或打开链接的能力)。


    default-src 'none';
    

    这收紧了政策,不允许来自任何地方的 XHR / Fetch / WebSockets / CSS / Font / JavaScript / Plugin 内容。这些都有各自的属性,但如果没有它们,则使用默认属性。您还没有尝试在您的 javascript 中执行任何这些操作。

    script-src 'unsafe-inline';
    

    这放宽了允许使用嵌入到页面中的任何 javascript 的政策。这包括 onclick/onhover 和整个 unsafe 属性系列。引用spec

    在任何一种情况下,作者都不应将“unsafe-inline”或 data: 作为其政策中的有效来源。两者都通过允许将代码直接包含在文档本身中来启用 XSS 攻击;最好完全避免它们。

    如果您觉得出于某种原因需要在文档本身中嵌入内容,则可以将哈希值和 nonce 值放在您的策略字符串中,以将您的内联脚本列入白名单。

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 2018-07-16
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多