内容安全策略和带有外部 <use> 的 SVG

Joh*_*ols 8 html javascript css svg content-security-policy

我已经使用以下定义设置了内容安全策略(CSP)style-src

style-src 'self' 'nonce-somenonce'
Run Code Online (Sandbox Code Playgroud)

然后,在我的标记中,我包含了 SVG,如下所示:

<svg role="img" title="Clock">
    <use xlink:href="/Content/Styles/svg/sprite.symbol.svg#icon-clock" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
Run Code Online (Sandbox Code Playgroud)

外部 SVG 包含多个带路径的符号:

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <symbol viewBox="0 0 40 40" id="arrow-right" xmlns="http://www.w3.org/2000/svg">
        <path d="M29 20l-5-5v4H11v2h13v4l5-5z"/>
    </symbol>
    <symbol viewBox="0 0 22 22" id="icon-clock" xmlns="http://www.w3.org/2000/svg">
        <path fill="#c20418" class="atcls-1" d="M17.727 9.777h-5.5v-5.5a1.222 ..."/>
    </symbol>
</svg>
Run Code Online (Sandbox Code Playgroud)

Chrome 拒绝允许此代码,并且我不知道如何在没有'unsafe-inline'. 根据这两个测试,SVG 不是 nonceable 元素:

  1. CSP 测试:'nonce-value' - 元素是否为 nonceable?
  2. CSP 测试:如何使 CSP 合规

我查看了这个线程,它建议将 SVG 分组为 a<style>和 nonce,但我不知道如何执行此操作,以及它是否适用于外部定义。

还有这个线程建议使用 JS 来设置样式,但我再次找不到这如何与 SVG 和<use>.

浏览器生成的报告如下所示:

{
  "csp-report": {
    "document-uri": "https://mypage.xyz/content/styles/svg/sprite.symbol.svg",
    "referrer": "",
    "violated-directive": "style-src-elem",
    "effective-directive": "style-src-elem",
    "original-policy": "default-src 'self';script-src 'strict-dynamic' 'nonce-LwpcXyjstsjZdWhOBquhhaxTEe+TFHbaAKYGal+sV3I=' 'unsafe-inline' 'unsafe-eval' http: https:;style-src 'self' 'nonce-LwpcXyjstsjZdWhOBquhhaxTEe+TFHbaAKYGal+sV3I=' 'unsafe-inline' fonts.googleapis.com;child-src 'self';connect-src 'self';img-src 'self';frame-src 'self';object-src 'none';font-src 'self';media-src 'self';manifest-src 'self';prefetch-src 'self';worker-src 'none';base-uri 'self';form-action 'self'; frame-ancestors 'self';upgrade-insecure-requests;report-uri /api/csp-reports",
    "disposition": "report",
    "blocked-uri": "inline",
    "line-number": 1,
    "source-file": "https://mypage.xyz/content/styles/svg/sprite.symbol.svg",
    "status-code": 0,
    "script-sample": ""
  }
} 
Run Code Online (Sandbox Code Playgroud)

即使报告指出违反了该指令,添加style-src-elem到标头也无法解决该问题。而这在 Firefox 中也根本没有实现。在 Chrome 中,我收到以下错误,该错误是矛盾的,因为即使在错误消息中也明确定义了随机数:

拒绝应用内联样式,因为它违反了以下内容安全策略指令:“style-src-elem 'self' 'nonce-Ma4zjvbuXdD3iwOLjAXsiJ2Qqk2TvVEQlT1efIY+qgE='”。启用内联执行需要“unsafe-inline”关键字、哈希值(“sha256-Ptir/SKEXaGsdPsQ11Srj5YgYg3GDQ1ZV8flKlU21lI=”)或随机数(“nonce-...”)。

gra*_*nty 2

代码如下:

<svg>
  <symbol viewBox="0 0 40 40" id="arrow-right" xmlns="http://www.w3.org/2000/svg">
    <path d="M29 20l-5-5v4H11v2h13v4l5-5z"/>
  </symbol>
</svg>
Run Code Online (Sandbox Code Playgroud)

当它从外部 SVG 嵌入时,<use>绝对不需要 'unsafe-inline'style-src.
您在此外部 SVG 中的某处使用了style=属性。

由于您使用的是 CSP 报告,因此只需将'report-sample'令牌添加到style-src指令中,您就会看到导致违规的代码示例。

请注意,通过 嵌入外部 SVG 时,Chrome 和 Firefox 浏览器的行为存在重大不一致<use>外部嵌入的style=属性
中的内联样式在 Firefox 中不违反 CSP,但在 Chrome 中违反 CSP。同时,尽管违反了 CSP, Crome 还是应用了内联style= 。外部 SVG 中的内联事件处理程序内置标记会在 Firefox 中导致 CSP 违规并被阻止,而在 Chrome 中,这些事件处理程序不会导致 CSP 违规,但根本不会执行。<use>