出于安全考虑,我已在公共网站中实施了CSP标头,并重构了代码以删除内联JavaScript的所有实例,例如onclick=foo()
和<a href='javascript: bar()'
。
我们最近与第三方集成,将代码注入页面。每个面向公众的页面都需要这样做。问题是他们的代码包含许多内联javascript(与上面提到的相同)并且违反了我们不允许内联脚本编写的CSP头文件。
我的理解是,如果您必须添加'unsafe-inline'
脚本,那么由于存在剩余的安全风险,您可能根本不会实施CSP。
我们可以更改每页的CSP标题,但由于每个页面都需要代码,因此它似乎全有或全无。
看起来您只允许'unsafe-inline'
仅用于页面的特定部分,或者我们可以将其用于该部分。
我唯一的选择是允许'unsafe-inline'
并击败CSP的全部内容吗?
答案 0 :(得分:3)
我唯一的选择是允许
'unsafe-inline'
并击败CSP的全部内容吗?
很有可能,是的。抱歉。但可能可以绕过它。
如果您确切知道第三方脚本将向您的网站注入哪些代码,则可以通过其哈希将CSP中的代码列入白名单。例如,如果您知道将注入以下脚本:
<script>alert("hello world");</script>
你可以计算
> Base64(SHA256('alert("hello world");'))
"1tD3lYbOBFeMLrXs+T9Tv9xEgcMsVs032rlMyrYSa0c="
并将以下内容添加到您的CSP中:
script-src 'sha256-1tD3lYbOBFeMLrXs+T9Tv9xEgcMsVs032rlMyrYSa0c='
当然,如果涉及多个内联脚本,这将极大地破坏您的策略的大小,并且除非这些脚本的内容绝对不变,否则它将根本不起作用。因此,这是否可行将在很大程度上取决于您的应用程序,以及您尝试保持兼容性的脚本。 (它可能会随着供应商更新该脚本而改变......)
答案 1 :(得分:0)
您可以使用nonce方法轻松实现这一目标,而无需使用unsafe-inline
。例如,Google使用{nonce}方法guide on how to integrate Tag Manager,这听起来像是您的用例示例。
简而言之,服务器使用此方法生成一次性的不可预测的令牌并设置CSP以允许它,然后将相同的令牌用于内联脚本。这样,服务器可以准确确定哪些内联脚本可以接受。