【问题标题】:'self' scripts being blocked from loading, but when I use the nonce they work?'self' 脚本被阻止加载,但是当我使用 nonce 时它们可以工作吗?
【发布时间】:2021-02-26 00:27:03
【问题描述】:

这可能有一个简单的解决方案,但我想不通。

我有一个这样定义的 CSP:

"Content-Security-Policy: default-src * 'unsafe-inline' 'unsafe-eval' data: blob:; style-src 'unsafe-inline' 'self' cdnjs.cloudflare.com fonts.googleapis.com; script-src www.google-analytics.com cdnjs.cloudflare.com 'self' 'nonce-". $_SESSION['nonce'] . "'; img-src * 'self' data:;object-src 'self' sias.dev:8000; connect-src * 'unsafe-inline'; frame-src 'self' sias.dev:8000 www.google.com;"

CSP 需要稍作调整,但可以部分工作。我需要一个随机数,因为我有一些带有一些内联脚本的旧网站。随机数是动态生成的,并在页面加载时更改。但是,我遇到了一个问题,我在通过 AJAX 调用的页面上加载了一些“自我”脚本(不是内联,而是脚本 src 标签。这可能是不好的做法,但我不想加载那些除了通过 ajax 调用的页面。

奇怪的是我在那个页面上没有任何内联脚本,只有像下面这样的脚本 src 标签,其中 nonce 是动态的并且与 CSP 策略中的匹配。

<script nonce = "" src="/js/create_dicom/js/plupload.full.min.js"></script>
<script nonce = "" src="/js/create_dicom/js/jquery.ui.plupload.min.js"></script>
<script nonce = "" src="/js/create_dicom/js/main.js"></script>
<script nonce = "" src="/bower/pdfjs/src/pdf.js"></script>
<script nonce = "" src="/bower/pdfjs/src/pdf.worker.js"></script>

当我不使用 nonce 时,我得到:

"Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”)."

当我使用 nonce 时,它​​们可以正常加载并且页面可以正常工作。我认为您只需要内联脚本的随机数而不是“自我”脚本。我应该以某种方式使用严格动态吗?我不需要在 script-src 标签的主页中使用随机数。他们在那里加载得很好?

另外,我需要 nonce 的地方大多是通过 AJAX 加载的页面上。有没有办法重构东西(即将它们放在 .js 文件中并以这种方式加载相关的 .js )。这有点痛苦,因为我没有脚本加载器,我只想为通过 AJAX 加载的文件加载相关的 js。

谢谢。

【问题讨论】:

    标签: javascript ajax content-security-policy nonce


    【解决方案1】:
    1. 控制台错误:The page’s settings blocked the loading of a resource at INLINE 说你肯定有一个内联脚本被阻止而不是外部,因此它与“自我”无关。您可以在控制台的右角查看 script_name:line_number:column 发生的位置。
      在 lock externall 脚本的情况下,错误类似于:The page’s settings blocked the loading of a resource at HTTPS://EXAMPLE.COM/PATH/SCRIPT.JS

    2. 可能是3种inline scripts&lt;script&gt;...&lt;script&gt;&lt;a href='javascript:void(0)'&lt;a onclick='evtHandler()'。 Firefox 不区分这些,Chrome 更冗长,所以看看它在 Chrome 浏览器中看起来如何。
      有 2 个选项:
      - Chrome 没有错误 - 这很好,false positive 违规知道 FF
      - Chrome 有错误 - 你有一个内联脚本,Chrome 会准确地说出哪个。

    3. 通过浏览器控制台日志调整 CSP 是不好的做法。你使用pdf.min.js,但是这个脚本包含一段代码:

    const n = document.createElement("script");
    n.src = e;
    n.onload = t;
    n.onerror = function() {
    r(new Error("Cannot load script at: " + n.src))
    };
    (document.head || document.documentElement).appendChild(n)

    这意味着可以在某些条件下加载一些外部脚本。只有上帝知道你需要按什么才能发生这种情况以及从何处加载此脚本。
    因此正确的方法(如果网站有访问者)是使用report-uri 指令并分析违规报告大约 2 周。

    PS:只是好奇-您指定:connect-src * 'unsafe-inline'; 所以您在某处确实有内联脚本?顺便说一句,connect-src 指令中没有使用 'unsafe-inline' 标记,它将被忽略。

    【讨论】:

    • 谢谢。 connect-src 的错误。我可能只是慢慢地重构代码,这样我就不需要随机数了。目前,大部分都在工作,但是在使用多个选项卡时我确实遇到了一个问题,因为每次页面加载都会生成一个新的随机数,所以这两个选项卡会有不同的随机数,然后 AJAX 请求不起作用。如果我在每个会话中使用一个随机数,这不是问题,但它是在每次页面加载时生成的。可能只需要重构,所以这不是问题。
    • 如果您不经常在&lt;script&gt;...&lt;/script&gt; 之间更改代码,'sha256-value' 标记将很有用:developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…。如果它的哈希出现在 script-src 指令中,它会自动允许内联脚本。 Chrome 浏览器自动计算所有被阻止的内联脚本的哈希值,只需查看控制台:Either the 'unsafe-inline' keyword, a hash ('sha256-RealHashIsHere'), or a nonce ('nonce -...') is required to enable inline execution。并且可以同时使用 and 'sha25-value' 和 'nonce-value'。
    • 无论哪种方式都可以。脚本大部分是静态的,因此使用散列是避免将它们放在单独的 .js 文件中的惰性方法。我最终会在我的 CSP 中放入相当多的哈希值。这是一个性能问题,或者标题的大小是否有限(显然 4-8K !永远不会接近那个)。
    猜你喜欢
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多