【问题标题】:Would this be a good idea against XSS?这对 XSS 来说是个好主意吗?
【发布时间】:2011-08-14 21:15:31
【问题描述】:

因为使用 Origin / X-Frame-Options http 标头并不是很流行,而且我认为 Firefox 中的新 CSP 不会更好(开销、复杂等)我想提出一个建议一个新的 JavaScript / ECMA 版本。

但首先我发布这个想法,这样你就可以说它是否不好。我称之为简单jsPolicy

每个使用 JavaScript 的人都在他的 html 头中放置了脚本。那么我们为什么不使用它们在那里添加我们的策略来控制所有后续脚本。示例:

<html>
<head>
<title>Example</title>
<script>
window.policy.inner = ["\nfunction foo(bar) {\n  return bar;\n}\n", "foo(this);"];
</script>
</head>
<body>
<script>
function foo(bar) {
  return bar;
}
</script>
<a href="#" onclick="foo(this);">Click Me</a>
<script>
alert('XSS');
</script>
</body>
</html>

现在浏览器将 .innerHTML 和 onclick.value 与策略中的值进行比较,因此最后一个脚本元素块不会被执行(忽略)。

当然,将所有内联代码加倍是没有用的,因此我们使用校验和。示例:

crc32("\nfunction foo(bar) {\n  return bar;\n}\n");

结果“1077388790”

现在是完整的例子:

if (typeof window.policy != 'undefined') {
  window.policy.inner = ["1077388790", "2501246156"];
  window.policy.url = ["http://code.jquery.com/jquery*.js","http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"];
  window.policy.relative = ["js/*.js"];
  window.policy.report = ["api/xssreport.php"];
}

浏览器只需要比较内联脚本的校验和是否在policy.inner中设置,或者script.src URL是否适合policy.url。

注意:policy.relative 背后的想法是只允许本地脚本:

window.policy.url = false;
window.policy.relative = ["js/*.js"];

注意:policy.report 应该与使用 CSP 完成的几乎相同(将被阻止的脚本和 url 发送到 api):
https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-unofficial-draft-20110315.html#violation-report-syntax

重要:

  • 政策不能设置两次(否则会引发警告)= 常量
  • 考虑一下:策略只能设置在头部(否则会引发警告)
  • 该策略仅用于检查作为 html 源的一部分的脚本,而不是那些即时放置的脚本。例子:
    document.write('
    您不需要为“http://code.jquery.com...”定义 policy.url,因为 policy.inner 校验和验证了完整的脚本源。这意味着即使 policy.url 设置为 false 也会加载源(是的,它仍然是安全的!)。这保证了该策略的简单用法。
  • 如果缺少其中一项策略,则没有限制。这意味着一个空的 policy.relative 导致所有本地文件都被允许。这保证了向后兼容性
  • 如果其中一个策略设置为“false”,则不允许使用(默认为 true)。例子:
    policy.inner = false;
    这不允许任何内联脚本
  • 该策略仅忽略不允许的脚本并向控制台发出警告(错误会停止执行允许的脚本,这不是必需的)

我认为这将使 XSS 成为不可能,而不是 CSP,它还可以避免持久性 XSS(只要没有人覆盖策略)并且更新起来会容易得多。

你怎么看?

编辑:
这是一个用 Javascript 制作的示例:
http://www.programmierer-forum.de/php/js-policy-against-xss.php

当然我们无法控制脚本的执行,但它显示了如果 jsPolicy 兼容的浏览器可以控制它是如何工作的。

EDIT2:
不要以为我在谈论编写一个小 javascript 函数来检测 xss!我的 jsPolicy 想法必须是新 JavaScript 引擎的一部分。您可以将其与放置在 .htaccess 文件中的 php 设置进行比较。您不能在运行时更改此设置。同样的要求也适用于 jsPolicy。你可以称它为global setting

jsPolicy 简而言之:
HTML 解析器 -> 将脚本发送到 JavaScript 引擎 -> 与 jsPolicy 比较 -> 是否允许?
A) 是的,通过 JavaScript 引擎执行
B) 不,忽略并将报告发送给网站管理员

EDIT3
引用 Mike's comment 这也是一个可能的设置:

window.policy.eval = false;

【问题讨论】:

  • 是的。如果这将成为新 Javascript / ECMA 版本的一部分,它将解决所有 XSS 问题。可能我解释得不好。你不清楚哪一部分?
  • 我更新了解释并添加了更多示例。我希望现在更清楚了。
  • 来自 MDC:“注意:出于安全原因,您不能使用 元素来配置 X-Content-Security-Policy 标头。”那是个很好的观点。您不能在客户端设置安全参数...如何安全?
  • @Rudie 我的想法是(如果浏览器符合策略要求),因为浏览器根据策略控制所有脚本执行。你知道为什么不允许 CSP 元数据吗?我认为这是因为您可以使用 JavaScript 覆盖元数据,并且忽略元数据比为不允许访问元数据的 javascript 引擎构建安全规则更容易。但我的想法没有可比的弱点,因为政策设置是不变的。
  • 但是在 HTTP 标头中设置策略至少同样安全,您不同意吗?我认为更安全。而且只有几个字节。可能比 cookie 还少(现在那些效率低下)。 edit 也比你建议发送每个请求的 JS 少。所有解决方案都有“开销”。

标签: javascript html security xss same-origin-policy


【解决方案1】:

这个想法经常被反复提及......每次安全专家都揭穿它。
听起来并不苛刻,但这不是开发问题,而是安全问题。具体来说,大多数开发人员没有意识到有多少变体、向量、漏洞利用和规避技术。

正如这里提到的其他一些答案,问题在于您的解决方案无法解决问题,即是否信任到达浏览器的任何内容,因为在客户端您无法知道什么是代码,什么是数据。即使您的解决方案也无法阻止这一点。

参见例如this question on ITsec.SE 了解实现此功能的一些实际问题。 (你的问题有点像那个问题的重复,或多或少......)

顺便说一句,重新 CSP - 检查此 other question on ITsec.SE

【讨论】:

  • @whitelist_dom_idea 很高兴看到其他人有类似的想法,但它有一个主要问题。对于破坏白名单元素的嵌套 xss 是不安全的。但是 jsPolicy 的漏洞在哪里?
  • @code_or_data 你为什么不知道?只有当它是代码时,它才会被转发到 javascript 引擎。即使 HTML 解析器有错误或浏览器插件,所以数据被视为代码并被转发到引擎,jsPolicy 是第一位的,因为它是引擎的一部分,而不是解析器。
【解决方案2】:

该策略仅用于检查作为 html 源代码的一部分的脚本,而不是那些即时放置的脚本。例子: document.write(''); 您不需要为“http://code.jquery.com...”定义 policy.url,因为 policy.inner 校验和验证了完整的脚本源。这意味着即使 policy.url 设置为 false 也会加载源(是的,它仍然是安全的!)。这保证了该策略的简单用法。

看来你已经把整个游戏都放在这里了。

如果我有类似的代码

// Pull parameters out of query string.
var match = location.search.match(/[&?]([^&=]+)=([^&]*)/);

window[decodeURIComponent(match[1])](decodeURIComponent(match[2]));

有人使用查询字符串?eval=alert%28%22pwned%22%29 诱骗用户访问我的网站,然后他们已被 XSSed 攻击,而您的策略没有采取任何措施来阻止它。

【讨论】:

  • 不错!但它不是像include($_GET['page'] . '.php'); 一样愚蠢,或者使用“123456”作为管理员密码吗?尽管您能够解决 99% 的 XSS,但您并没有意识到这个想法?!我真的很感谢这个例子,但是如果 eval(通过 POST/GET/COOKIE)是系统中唯一的漏洞,并且只有代码不安全,那么通过policy.eval = false 扩展策略呢?而且 CSP 也无法帮助您抵御攻击。
  • 系统漏洞很大。 javascript: 来自第三方的 URL,XSS 通过来自第三方的 HTML。实际上,列出它停止的 XSS 向量可能比列出它没有停止的 XSS 向量更容易。
  • 请给出代码示例。您想如何将 javascript 代码放置在第三方脚本的 url 中。或者你的意思是如果像 jquery 这样的第三方服务器被黑了?在这里没有任何技术会有所帮助。这就是为什么只有在您不信任第三方时才应该使用本地脚本的原因。但这不是政策的漏洞。它是第三方的一个洞。还是您的意思是script.src url中的xss?这不起作用,因为 javascript:alert('xss') 意味着添加策略不允许的内联脚本。来自第三方的 html 是什么意思?如果它的内联代码也是不允许的。
  • @mgutt, myLink.href = linkFromThirdParty 不在您的保单范围内。 CSS 既不像 p { color: expression(alert(1337)) },也不像 myDiv.innerHTML = textFromThirdParty。通过仅检查脚本,您会丢失大多数 XSS 向量。
  • css 被覆盖,因为它是内联代码。我不知道 myLink.href 是如何填充的。你的意思是如果有人入侵了 jquery 服务器并将错误代码放入jquery-1.5.2.min.js? xss 只是结果(服务器攻击先行)。如果您不信任 jquery,则需要将文件复制到 localhost。
【解决方案3】:

跨站点脚本发生在客户端。您的策略是在客户端定义的。看到问题了吗?

我喜欢内容安全策略,并且在我的所有项目中都使用它。事实上,我正在开发一个 JavaScript 框架,它的要求之一是“对 CSP 友好”。

CSP > crossdomain.xml > 你的策略。

【讨论】:

  • CSP 也是客户端。考虑一下。您在标头中定义规则,客户端浏览器会遵循 CSP 规范并在需要时停止执行。如果浏览器坚持使用 jsPolicy,那将是相同的。我希望你不要认为我在谈论编写一个 js 函数或类似的东西。这应该是对 Javascript 引擎本身的真正更新,并添加了新的“全局常量”。
  • 您可以将 jsPolicy 与 .htaccess 文件中的 php 设置进行比较。它不能在运行时更改。
  • CSP 不是客户端。 Web 服务器发送一个 HTTP 标头,浏览器抓取该标头并对其进行操作。此时甚至不存在包含 DOM 和 JavaScript 的整个文档。客户端时代始于 CSP 之后。否则,CSP 将无法工作。他们决定不允许通过元标记设置 CSP 策略是有原因的。
【解决方案4】:

绝大多数 XSS 攻击来自“可信”来源,至少就浏览器而言。它们通常是回显用户输入的结果,例如在论坛中,并且没有正确转义输入。您永远不会通过链接到 jquery 获得 XSS,而且您会从任何其他链接来源获得 XSS 的情况非常

如果您尝试执行跨域脚本,则无法获得远程脚本的校验和。

所以虽然你的想法看起来不错,但我真的不明白这一点。

【讨论】:

  • 你说的是持久性 XSS,这不是 CSP 涵盖的,但它是我的想法。论坛帖子中的 XSS 意味着回显“”。但它没有用,因为在 policy.inner 中没有设置 alert('xss') 的校验和。如果 xss 是“”,情况也是如此。该 url 不是 policy.url 的一部分,无法加载。你现在明白我的想法了吗?
  • 啊,好吧。我仍然没有真正看到外部引用的意义,而且我认为您要求开发人员承担很多开销(好吧,不是很多,但不仅仅是删除链接在)。就亲戚而言,foo.php?js/foo.js 在技术上是匹配的。总的来说,我开始接受这个想法,但我认为要求人们计算校验和不会飞,尤其是对于不知道校验和是什么的新开发人员:) 人们也不喜欢重新输入 URL ,尤其是在可能包含来自 20 多个部分或视图的 JS 的系统中。
  • 就“论坛 xss”预防而言,我最好的想法是创建一个 &lt;noScriptBelowThis&gt; 标记,但这当然会阻止将脚本放置在 &lt;/head&gt; 之前的速度优化
  • @noScriptBelowThis 这样的标签与 smarty 中的 {literal} 标签“相似”。一个非常短的 -Tag 可以最大限度地减少开销。但这对脚本内部的 xss 没有帮助,例如带有 onsubmit 事件的搜索表单。但这很容易理解,所以也为此点赞 ;)
  • @high_demand_on_developers 看看CSP Specification。什么会更容易?校验和的事情并不容易,你是对的。但是使用 PHP 自动设置这些校验和/url 是没有问题的:1. 获取模板文件的filemtime(),2. 如果更改了preg_match() 脚​​本,3. 获取 url 或crc32() 校验和 4. 覆盖策略设置一般的js文件。但是不要想那个。考虑一下禁止所有内联脚本并只允许一个本地js文件夹和一个完整的外部脚本作为src的好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
相关资源
最近更新 更多