我注意到 GitHub 和 Facebook 现在都在实施这项政策,这限制了第三方脚本在他们的体验/站点中运行。
有没有办法使用JavaScript检测文档是否针对 CSP 运行?我正在编写一个小书签,如果用户所在的网站不支持嵌入脚本标签,我想给他们一条消息。
我注意到 GitHub 和 Facebook 现在都在实施这项政策,这限制了第三方脚本在他们的体验/站点中运行。
有没有办法使用JavaScript检测文档是否针对 CSP 运行?我正在编写一个小书签,如果用户所在的网站不支持嵌入脚本标签,我想给他们一条消息。
您可以尝试使用事件捕获 CSP 违规错误"securitypolicyviolation"
来自:https ://developer.mozilla.org/en-US/docs/Web/API/SecurityPolicyViolationEvent
例子:
document.addEventListener("securitypolicyviolation", (e) => {
console.log(e.blockedURI);
console.log(e.violatedDirective);
console.log(e.originalPolicy);
});
那这个呢。对于慢速连接,可能应该提高超时。Onload 是我用来检测它的,它似乎有效。如果它加载,则显然 CSP 未启用或配置不正确。
var CSP = 0;
frame = document.createElement('script');
frame.setAttribute('id', 'theiframe');
frame.setAttribute('src', location.protocol+'//example.com/');
frame.setAttribute('onload', 'CSP=1;');
document.body.appendChild(frame);
setTimeout(function(){if (0 == CSP){alert("CSP IS ENABLED");}}, 250);
来自https://github.com/angular/angular.js/blob/master/src/Angular.js#L1091,函数noUnsafeEval
function noUnsafeEval() {
try {
/* jshint -W031, -W054 */
new Function('');
/* jshint +W031, +W054 */
return false;
} catch (e) {
return true;
}
}
目前,在发布浏览器时没有办法这样做。
但是,按照规范,以下内容应该可以工作,并且在 Chrome 中启用了实验性 Web 平台功能chrome://flags/
:
function detectCSPInUse() {
return "securityPolicy" in document ? document.securityPolicy.isActive : false;
}
接口(如果它被实现,SecurityPolicy
你会得到什么document.securityPolicy
)有一些属性可以提供更多关于当前允许的细节。
检测对 CSP 的支持的一种简单方法是检查 JavaScript 的 eval() 方法是否可以在不引发错误的情况下运行,如下所示:
try {
eval("return false;");
} catch (e) {
return true;
}
但是,这仅在实际打开 CSP(显然)时才有效,并且在加载页面的响应标头中设置了 Content-Security-Policy,并且在 script-src 中没有“unsafe-eval”。
我来这里是为了寻找一种在没有实际打开 CSP 的情况下检测浏览器中的 CSP 支持的方法。不过,这似乎是不可能的。
附带说明一下,IE 不支持 CSP,只有 IE 10+ 中的沙箱指令,通过查看 CSP 标准,它不会使其成为符合标准的 Web 浏览器。
fetch(document.location.href)
.then(resp => {
const csp = resp.headers.get('Content-Security-Policy');
// does this exist? Is is any good?
});
然而,这将失败connect-src='none'
并被报告。