Content-Security-Policy: style-src 指令

Baseline 已广泛支持

此功能已相当成熟,可在多种设备和浏览器版本上运行。自 ⁨2016 年 8 月⁩ 起,所有浏览器均已提供此功能。

HTTP Content-Security-Policy (CSP) 的 style-src 指令指定了样式表的有效来源。

CSP 版本 1
指令类型 获取指令
default-src 回退 是的。如果此指令缺失,用户代理将查找 default-src 指令。

语法

http
Content-Security-Policy: style-src 'none';
Content-Security-Policy: style-src <source-expression-list>;

此指令可以具有以下值之一

'none'

不允许加载此类型的任何资源。单引号是强制性的。

<source-expression-list>

一个由源表达式值组成的空格分隔列表。如果资源类型与任何给定的源表达式匹配,则可以加载此类资源。对于此指令,以下源表达式值适用:

请注意,规范中也包含了 'unsafe-eval' 作为有效的源表达式值,以允许解析和插入 CSS 字符串的 CSSOM 方法,包括 insertRule() 方法以及各种接口上的 cssText setter,例如 CSSStyleSheet.insertRule()CSSStyleDeclaration.cssText。然而,目前没有浏览器会阻止这些方法,因此无需应用 unsafe-eval

示例

违规情况

给定此 CSP 头

http
Content-Security-Policy: style-src https://example.com/

以下样式表将被阻止,无法加载:

html
<link href="https://not-example.com/styles/main.css" rel="stylesheet" />

<style>
  #inline-style {
    background: red;
  }
</style>

<style>
  @import "https://not-example.com/styles/print.css" print;
</style>

以及使用 Link 头加载的样式:

http
Link: <https://not-example.com/styles/stylesheet.css>;rel=stylesheet

内联样式属性也将被阻止:

html
<div style="display:none">Foo</div>

以及通过直接设置 style 属性或设置 cssText 在 JavaScript 中应用的样式:

js
document.querySelector("div").setAttribute("style", "display:none;");
document.querySelector("div").style.cssText = "display:none;";

然而,直接在元素的 style 属性上设置的样式属性将不会被阻止,允许用户通过 JavaScript 安全地操作样式:

js
document.querySelector("div").style.display = "none";

可以通过 script-src CSP 指令禁止 JavaScript 来防止这些类型的操作。

不安全的内联样式

注意:禁止内联样式和内联脚本是 CSP 提供的最大安全优势之一。但是,如果你绝对必须使用它们,有几种机制可以允许它们。

要允许内联样式,可以指定 'unsafe-inline'、一个 nonce-source 或一个与内联块匹配的 hash-source。以下内容安全策略将允许像 <style> 元素和任何元素上的 style 属性这样的内联样式:

http
Content-Security-Policy: style-src 'unsafe-inline';

以下 <style> 元素和 style 属性将受策略允许:

html
<style>
  #inline-style {
    background: red;
  }
</style>

<div style="display:none">Foo</div>

你可以使用 nonce-source 来只允许特定的内联样式块。你需要生成一个随机 nonce 值(使用加密安全的随机令牌生成器)并将其包含在策略中。重要的是,此 nonce 值需要动态生成,因为它必须对每个 HTTP 请求都是唯一的。

http
Content-Security-Policy: style-src 'nonce-2726c7f26c'

你必须在 <style> 元素上设置相同的 nonce:

html
<style nonce="2726c7f26c">
  #inline-style {
    background: red;
  }
</style>

或者,你可以从内联样式创建哈希。CSP 支持 sha256、sha384 和 sha512。哈希的二进制形式必须用 base64 编码。你可以通过 openssl 程序在命令行上获取字符串的哈希:

bash
echo -n "#inline-style { background: red; }" | openssl dgst -sha256 -binary | openssl enc -base64

你可以使用 hash-source 来只允许特定的内联样式块。

http
Content-Security-Policy: style-src 'sha256-ozBpjL6dxO8fsS4u6fwG1dFDACYvpNxYeBA6tzR+FY8='

生成哈希时,不要包含 <style> 标签,并且请注意大小写和空格(包括前导或尾随空格)都很重要。

html
<style>
  #inline-style {
    background: red;
  }
</style>

规范

规范
内容安全策略级别 3
# directive-style-src

浏览器兼容性

另见