如何检测内容安全策略 (CSP)

How to detect Content Security Policy (CSP)

本文关键字:CSP 安全策略 检测 何检测      更新时间:2023-09-26

我注意到GitHub和Facebook现在都在实施这项政策,该政策限制了第三方脚本在其体验/站点内运行。

有没有办法使用 JavaScript 检测文档是否针对 CSP 运行?我正在编写一个书签,如果用户所在的站点不支持嵌入脚本标记,我想向用户发送消息。

可以尝试使用事件"securitypolicyviolation"捕获 CSP 违规错误

寄件人: 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);
});

从 https://github.com/angular/angular.js/blob/cf16b241e1c61c22a820ed8211bc2332ede88e62/src/Angular.js#L1150-L1158,函数noUnsafeEval

function noUnsafeEval() {
  try {
    /* jshint -W031, -W054 */
    new Function('');
    /* jshint +W031, +W054 */
    return false;
  } catch (e) {
    return true;
  }
}

这个呢?对于慢速连接,可能应该提高超时。加载是我用来检测它的,它似乎有效。如果它加载,则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://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5:

fetch(document.location.href)
.then(resp => {
  const csp = resp.headers.get('Content-Security-Policy');
  // does this exist? Is is any good?
});

但是,这将在connect-src='none'失败并被报告。

检测对CSP支持的一种简单方法是检查JavaScript的eval()方法是否可以在不抛出错误的情况下运行,如下所示:

try {
    eval("return false;");
} catch (e) {
    return true;
}

但是,这仅在CSP实际打开时才有效(显然),在页面加载的响应标头中设置了内容安全策略,并且在script-src中没有"unsafe-eval"。

我来到这里是为了寻找一种方法来检测浏览器中的 CSP 支持,而无需实际打开 CSP。不过,这似乎是不可能的。

附带说明一下,IE不支持CSP,仅支持IE 10+中的沙盒指令,通过查看CSP标准,它并不能使其成为一致的Web浏览器。

目前,在发布浏览器中无法执行此操作。

但是,根据规范,以下内容应该可以工作,并且在 Chrome 中启用了实验性网络平台功能chrome://flags/

function detectCSPInUse() {
  return "securityPolicy" in document ? document.securityPolicy.isActive : false;
}

SecurityPolicy接口(如果实现,您从document.securityPolicy获得的内容)具有一些属性,这些属性提供了有关当前允许的内容的更多详细信息。

我正在检查书签代码中的错误事件,并在脚本未加载时提示用户安装我的扩展。

javascript:(function(){
var s=document.createElement('script');
s.setAttribute('type','text/javascript');
s.setAttribute('src','https://example.ru/bookmarklet?hostname=%27+encodeURIComponent(location.hostname));
s.setAttribute('onerror', 'if(confirm(`Downloading from the site is possible only through the "MyExtensionName" extension. Install extension?`)){window.open("https://chrome.google.com/webstore/detail/myextensionlink");}');
document.body.appendChild(s);})();