安全标头快速参考

了解更多关于可以保护您的网站安全的标头,并快速查找最重要的详细信息。

本文列出了您可以用来保护网站的最重要的安全标头。使用它来了解基于 Web 的安全功能,学习如何在您的网站上实施这些功能,并作为您需要提醒时的参考。

建议处理敏感用户数据的网站使用的安全标头
内容安全策略 (CSP)
可信类型
建议所有网站使用的安全标头
X-Content-Type-Options
X-Frame-Options
跨域资源策略 (CORP)
跨域打开器策略 (COOP)
HTTP 严格传输安全 (HSTS)
具有高级功能的网站的安全标头
跨域资源共享 (CORS)
跨域嵌入器策略 (COEP)
Web 上已知的威胁
在深入了解安全标头之前,请先了解 Web 上已知的威胁以及您为什么要使用这些安全标头。

在深入了解安全标头之前,请先了解 Web 上已知的威胁以及您为什么要使用这些安全标头。

保护您的站点免受注入漏洞的攻击

当您的应用程序处理的不受信任的数据会影响其行为,并通常导致执行攻击者控制的脚本时,就会出现注入漏洞。由注入错误引起的最常见漏洞是跨站脚本 (XSS) 及其各种形式,包括反射型 XSS存储型 XSSDOM 型 XSS 和其他变体。

XSS 漏洞通常可以让攻击者完全访问应用程序处理的用户数据以及托管在同一Web 源中的任何其他信息。

传统的注入防御措施包括始终如一地使用自动转义 HTML 模板系统、避免使用危险的 JavaScript API,以及通过将文件上传托管在单独的域中并清理用户控制的 HTML 来正确处理用户数据。

  • 使用内容安全策略 (CSP)来控制您的应用程序可以执行哪些脚本,以降低注入风险。
  • 使用可信类型来强制清理传递到危险 JavaScript API 的数据。
  • 使用X-Content-Type-Options来防止浏览器错误地解释您网站资源的 MIME 类型,这可能会导致脚本执行。

将您的站点与其他网站隔离

Web 的开放性允许网站以可能违反应用程序安全期望的方式相互交互。这包括意外地发出经过身份验证的请求,或者将来自另一个应用程序的数据嵌入到攻击者的文档中,从而允许攻击者修改或读取应用程序数据。

破坏 Web 隔离的常见漏洞包括点击劫持跨站请求伪造 (CSRF)、跨站脚本包含 (XSSI) 和各种跨站泄漏

后 Spectre Web 开发如果您对这些标头感兴趣,这是一篇很棒的读物。

安全地构建强大的网站

Spectre 将加载到同一浏览上下文组中的任何数据都可能被读取,尽管有同源策略。浏览器限制了可能利用“跨域隔离”特殊环境背后的漏洞的功能。通过跨域隔离,您可以使用强大的功能,例如 SharedArrayBuffer

加密到您站点的流量

当应用程序未完全加密传输中的数据时,就会出现加密问题,从而使窃听攻击者能够了解用户与应用程序的交互。

以下情况可能会导致加密不足:不使用 HTTPS、混合内容、设置 Cookie 时未设置Secure 属性(或 __Secure 前缀)或 宽松的 CORS 验证逻辑

内容安全策略 (CSP)

跨站脚本 (XSS)是一种攻击,其中网站上的漏洞允许注入和执行恶意脚本。

Content-Security-Policy 提供了一个额外的层来缓解 XSS 攻击,方法是限制页面可以执行哪些脚本。

建议您使用以下方法之一启用严格 CSP

  • 如果您在服务器上渲染 HTML 页面,请使用基于 nonce 的严格 CSP
  • 如果您的 HTML 必须静态提供或缓存,例如,如果它是一个单页应用程序,请使用基于哈希的严格 CSP

用法示例:基于 nonce 的 CSP

Content-Security-Policy:
  script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';
如何使用 CSP

1. 使用基于 nonce 的严格 CSP {: #nonce-based-csp}

如果您在服务器上渲染 HTML 页面,请使用基于 nonce 的严格 CSP

在服务器端为每个请求生成一个新的脚本 nonce 值,并设置以下标头

服务器配置文件

Content-Security-Policy:
  script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';

在 HTML 中,为了加载脚本,请将所有 <script> 标记的 nonce 属性设置为相同的 {RANDOM1} 字符串。

index.html

<script nonce="{RANDOM1}" src="https://example.com/script1.js"></script>
<script nonce="{RANDOM1}">
  // Inline scripts can be used with the <code>nonce</code> attribute.
</script>

Google 相册是一个很好的基于 nonce 的严格 CSP 示例。使用 DevTools 查看它是如何使用的。

2. 使用基于哈希的严格 CSP {: #hash-based-csp}

如果您的 HTML 必须静态提供或缓存,例如,如果您正在构建单页应用程序,请使用基于哈希的严格 CSP

服务器配置文件

Content-Security-Policy:
  script-src 'sha256-{HASH1}' 'sha256-{HASH2}' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';

在 HTML 中,您需要内联您的脚本才能应用基于哈希的策略,因为 大多数浏览器不支持哈希外部脚本

index.html

<script>
...// your script1, inlined
</script>
<script>
...// your script2, inlined
</script>

要加载外部脚本,请阅读 选项 B:基于哈希的 CSP 响应标头 部分下的“动态加载源脚本”。

CSP Evaluator 是一个评估您的 CSP 的好工具,但同时也是一个很好的基于 nonce 的严格 CSP 示例。使用 DevTools 查看它是如何使用的。

支持的浏览器

关于 CSP 的其他注意事项

  • frame-ancestors 指令可以保护您的网站免受点击劫持的攻击,如果您允许不受信任的站点嵌入您的网站,则会存在这种风险。如果您更喜欢更简单的解决方案,可以使用 X-Frame-Options 来阻止加载,但 frame-ancestors 为您提供了高级配置,仅允许特定来源作为嵌入器。
  • 您可能已经使用了 CSP 来确保您的网站的所有资源都通过 HTTPS 加载。这已经变得不太相关:如今,大多数浏览器都会阻止混合内容
  • 您还可以在 仅报告模式 中设置 CSP。
  • 如果您无法在服务器端将 CSP 设置为标头,您也可以将其设置为元标记。请注意,您不能对元标记使用 仅报告 模式(尽管这可能会改变)。

了解更多

可信类型

DOM 型 XSS 是一种攻击,其中恶意数据被传递到支持动态代码执行的接收器,例如 eval().innerHTML

可信类型提供了编写、安全审查和维护没有 DOM XSS 的应用程序的工具。它们可以通过 CSP 启用,并通过限制危险的 Web API 仅接受特殊对象(可信类型)来使 JavaScript 代码默认安全。

要创建这些对象,您可以定义安全策略,在其中您可以确保在将数据写入 DOM 之前始终如一地应用安全规则(例如转义或清理)。然后,这些策略是代码中唯一可能引入 DOM XSS 的地方。

用法示例

Content-Security-Policy: require-trusted-types-for 'script'
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
  // Name and create a policy
  const policy = trustedTypes.createPolicy('escapePolicy', {
    createHTML: str => {
      return str.replace(/\</g, '&lt;').replace(/>/g, '&gt;');
    }
  });
}

// Assignment of raw strings is blocked by Trusted Types.
el.innerHTML = &#39;some string&#39;; // This throws an exception.

// Assignment of Trusted Types is accepted safely.
const escaped = policy.createHTML(&#39;&lt;img src=x onerror=alert(1)&gt;&#39;);
el.innerHTML = escaped;  // &#39;&amp;lt;img src=x onerror=alert(1)&amp;gt;&#39;

如何使用可信类型

  1. 对危险的 DOM 接收器强制执行可信类型 CSP 和可信类型标头:

    Content-Security-Policy: require-trusted-types-for 'script'

    目前,'script'require-trusted-types-for 指令的唯一可接受值。

    当然,您可以将可信类型与其他 CSP 指令结合使用

将上面的基于 nonce 的 CSP 与可信类型合并

Content-Security-Policy:
  script-src &#39;nonce-{RANDOM1}&#39; &#39;strict-dynamic&#39; https: &#39;unsafe-inline&#39;;
  object-src &#39;none&#39;;
  base-uri &#39;none&#39;;
  require-trusted-types-for &#39;script&#39;;

<aside class="note"><b>Note: </b> You may limit allowed Trusted Types policy names by setting an additional <code>trusted-types</code> directive (for example, <code>trusted-types myPolicy</code>). However, this is not a requirement. </aside>

  1. 定义策略

    策略

    // Feature detection
    if (window.trustedTypes && trustedTypes.createPolicy) {
      // Name and create a policy
      const policy = trustedTypes.createPolicy('escapePolicy', {
        createHTML: str => {
          return str.replace(/\/g, '>');
        }
      });
    }
  2. 应用策略

    在将数据写入 DOM 时使用策略

    // Assignment of raw strings are blocked by Trusted Types.
    el.innerHTML = &#39;some string&#39;; // This throws an exception.</p>
    
    <p>// Assignment of Trusted Types is accepted safely.
    const escaped = policy.createHTML(&#39;<img src="x" onerror="alert(1)">&#39;);
    el.innerHTML = escaped;  // &#39;&lt;img src=x onerror=alert(1)&gt;&#39;

    使用 require-trusted-types-for 'script',使用可信类型是一项要求。使用字符串的任何危险 DOM API 都会导致错误。

支持的浏览器

了解更多

X-Content-Type-Options

当从您的域提供恶意 HTML 文档时(例如,如果上传到照片服务的图像包含有效的 HTML 标记),某些浏览器会将其视为活动文档,并允许它在应用程序的上下文中执行脚本,从而导致跨站脚本错误

X-Content-Type-Options: nosniff 通过指示浏览器在给定响应的 Content-Type 标头中设置的 MIME 类型 是正确的来防止这种情况。建议您的所有资源都使用此标头。

用法示例

X-Content-Type-Options: nosniff
如何使用 X-Content-Type-Options

建议从您的服务器提供的所有资源都使用 X-Content-Type-Options: nosniff 以及正确的 Content-Type 标头。

X-Content-Type-Options: nosniff

与文档 HTML 一起发送的标头示例

X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8

支持的浏览器

浏览器支持

  • Chrome: 64.
  • Edge: 12.
  • Firefox: 50.
  • Safari: 11.

来源

了解更多

X-Frame-Options

如果恶意网站可以将您的网站嵌入为 iframe,这可能会使攻击者通过点击劫持来调用用户的非预期操作。此外,在某些情况下,Spectre 型攻击使恶意网站有机会了解嵌入文档的内容。

X-Frame-Options 指示是否应允许浏览器在 <frame><iframe><embed><object> 中渲染页面。建议所有文档都发送此标头,以指示它们是否允许被其他文档嵌入。

用法示例

X-Frame-Options: DENY
如何使用 X-Frame-Options

所有不打算嵌入的文档都应使用 X-Frame-Options 标头。

您可以尝试以下配置如何影响在 此演示上加载 iframe。更改 X-Frame-Options 下拉菜单,然后单击重新加载 iframe 按钮。

保护您的网站不被任何其他网站嵌入

拒绝被任何其他文档嵌入。

X-Frame-Options: DENY
X-Frame-Options: DENY

保护您的网站不被任何跨域网站嵌入

仅允许被同源文档嵌入。

X-Frame-Options: SAMEORIGIN

支持的浏览器

浏览器支持

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 4.

来源

了解更多

跨域资源策略 (CORP)

攻击者可以嵌入来自另一个来源的资源,例如来自您的站点,通过利用基于 Web 的 跨站泄漏来了解有关它们的信息。

Cross-Origin-Resource-Policy 通过指示可以加载它的网站集来缓解此风险。标头采用三个值之一:same-originsame-sitecross-origin。建议所有资源都发送此标头,以指示它们是否允许被其他网站加载。

用法示例

Cross-Origin-Resource-Policy: same-origin
如何使用 CORP

建议所有资源都使用以下三个标头之一提供服务。

您可以尝试以下配置如何影响在 Cross-Origin-Embedder-Policy: require-corp 环境下在 此演示中加载资源。更改跨域资源策略下拉菜单,然后单击重新加载 iframe重新加载图像按钮以查看效果。

允许跨域加载资源 cross-origin

建议类似 CDN 的服务将 cross-origin 应用于资源(因为它们通常由跨域页面加载),除非它们已经通过 CORS 提供服务,后者具有类似的效果。

Cross-Origin-Resource-Policy: cross-origin
Cross-Origin-Resource-Policy: cross-origin

将资源限制为从 same-origin 加载

same-origin 应应用于仅打算由同源页面加载的资源。您应该将其应用于包含有关用户的敏感信息或仅打算从同一来源调用的 API 响应的资源。

请记住,带有此标头的资源仍然可以直接加载,例如,通过在新浏览器窗口中导航到 URL。跨域资源策略仅保护资源免受其他网站的嵌入。

Cross-Origin-Resource-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin

将资源限制为从 same-site 加载

same-site 建议应用于与上述类似的资源,但旨在由您网站的其他子域加载。

Cross-Origin-Resource-Policy: same-site
Cross-Origin-Resource-Policy: same-site

支持的浏览器

浏览器支持

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 74.
  • Safari: 12.

来源

了解更多

跨域打开器策略 (COOP)

攻击者的网站可以在弹出窗口中打开另一个站点,通过利用基于 Web 的 跨站泄漏来了解有关它的信息。在某些情况下,这也可能允许利用基于 Spectre 的侧信道攻击。

Cross-Origin-Opener-Policy 标头提供了一种文档将其自身与通过 window.open() 或带有 target="_blank" 而没有 rel="noopener" 的链接打开的跨域窗口隔离的方法。因此,文档的任何跨域打开器都将没有对它的引用,并且将无法与其交互。

用法示例

Cross-Origin-Opener-Policy: same-origin-allow-popups
如何使用 COOP

您可以尝试以下配置如何影响与 此演示上的跨域弹出窗口的通信。更改文档和弹出窗口的跨域打开器策略下拉菜单,单击打开弹出窗口按钮,然后单击发送 postMessage 以查看消息是否实际传递。

将文档与跨域窗口隔离

设置 same-origin 会将文档与跨域文档窗口隔离。

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin

将文档与跨域窗口隔离,但允许弹出窗口

设置 same-origin-allow-popups 允许文档保留对其弹出窗口的引用,除非它们使用 same-originsame-origin-allow-popups 设置 COOP。这意味着 same-origin-allow-popups 仍然可以保护文档在作为弹出窗口打开时被引用,但允许它与其自己的弹出窗口进行通信。

Cross-Origin-Opener-Policy: same-origin-allow-popups
Cross-Origin-Opener-Policy: same-origin-allow-popups

允许文档被跨域窗口引用

unsafe-none 是默认值,但您可以显式指示此文档可以由跨域窗口打开并保留相互访问权限。

Cross-Origin-Opener-Policy: unsafe-none
Cross-Origin-Opener-Policy: unsafe-none

报告与 COOP 不兼容的模式

当 COOP 使用 Reporting API 阻止跨窗口交互时,您可以接收报告。

Cross-Origin-Opener-Policy: same-origin; report-to="coop"

COOP 也支持仅报告模式,因此您可以接收报告,而无需实际阻止跨源文档之间的通信。

Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop"

支持的浏览器

浏览器支持

  • Chrome: 83.
  • Edge: 83.
  • Firefox: 79.
  • Safari: 15.2.

来源

了解更多

跨域资源共享 (CORS)

与本文中的其他项不同,跨源资源共享 (CORS) 不是标头,而是一种浏览器机制,用于请求和允许访问跨源资源。

默认情况下,浏览器会强制执行同源策略,以防止网页访问跨源资源。例如,当加载跨源图片时,即使它在网页上以视觉方式显示,页面上的 JavaScript 也无法访问该图片的数据。资源提供商可以放宽限制,并通过选择加入 CORS 来允许其他网站读取资源。

用法示例

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
如何使用 CORS

在研究如何配置 CORS 之前,了解请求类型之间的区别很有帮助。根据请求详细信息,请求将被分类为简单请求预检请求

简单请求的标准

  • 方法是 GETHEADPOST
  • 自定义标头仅包括 AcceptAccept-LanguageContent-LanguageContent-Type
  • Content-Typeapplication/x-www-form-urlencodedmultipart/form-datatext/plain

其他所有内容都归类为预检请求。有关更多详细信息,请查看 跨源资源共享 (CORS) - HTTP | MDN

简单请求

当请求满足简单请求标准时,浏览器会发送一个带有 Origin 标头的跨源请求,该标头指示请求来源。

请求标头示例

Get / HTTP/1.1
Origin: https://example.com

响应标头示例

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
  • Access-Control-Allow-Origin: https://example.com 表示 https://example.com 可以访问响应的内容。旨在供任何站点读取的资源可以将此标头设置为 *,在这种情况下,浏览器将仅要求请求在不使用凭据的情况下发出。
  • Access-Control-Allow-Credentials: true 表示允许携带凭据(cookie)的请求加载资源。否则,即使请求来源存在于 Access-Control-Allow-Origin 标头中,经过身份验证的请求也会被拒绝。

您可以尝试在 Cross-Origin-Embedder-Policy: require-corp 环境下在此演示中简单请求如何影响资源加载。单击跨源资源共享复选框,然后单击重新加载图像按钮以查看效果。

预检请求

预检请求之前会发送一个 OPTIONS 请求,以检查是否允许发送后续请求。

请求标头示例

OPTIONS / HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
  • Access-Control-Request-Method: POST 允许使用 POST 方法发出以下请求。
  • Access-Control-Request-Headers: X-PINGOTHER, Content-Type 允许请求者在后续请求中设置 X-PINGOTHERContent-Type HTTP 标头。

响应标头示例

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
  • Access-Control-Allow-Methods: POST, GET, OPTIONS 表示可以使用 POSTGETOPTIONS 方法发出后续请求。
  • Access-Control-Allow-Headers: X-PINGOTHER, Content-Type 表示后续请求可以包括 X-PINGOTHERContent-Type 标头。
  • Access-Control-Max-Age: 86400 表示预检请求的结果可以缓存 86400 秒。

支持的浏览器

浏览器支持

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 4.

来源

了解更多

跨域嵌入器策略 (COEP)

为了降低基于 Spectre 的攻击窃取跨源资源的能力,默认情况下禁用 SharedArrayBufferperformance.measureUserAgentSpecificMemory() 等功能。

Cross-Origin-Embedder-Policy: require-corp 阻止文档和 worker 加载跨源资源,例如图像、脚本、样式表、iframe 和其他资源,除非这些资源通过 CORSCORP 标头显式选择加入加载。COEP 可以与 Cross-Origin-Opener-Policy 结合使用,以使文档选择加入跨源隔离

当您要为文档启用跨源隔离时,请使用 Cross-Origin-Embedder-Policy: require-corp

用法示例

Cross-Origin-Embedder-Policy: require-corp
如何使用 COEP

用法示例

COEP 采用 require-corp 的单个值。通过发送此标头,您可以指示浏览器阻止加载未通过 CORSCORP 选择加入的资源。

How COEP works

您可以尝试以下配置如何影响此演示上的资源加载。更改跨源嵌入器策略下拉菜单、跨源资源策略下拉菜单、仅报告复选框等,以查看它们如何影响资源加载。此外,打开报告端点演示以查看是否报告了被阻止的资源。

启用跨源隔离

通过发送 Cross-Origin-Embedder-Policy: require-corp 以及 Cross-Origin-Opener-Policy: same-origin 来启用跨源隔离

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

报告与 COEP 不兼容的资源

您可以使用 Reporting API 接收由 COEP 引起的被阻止资源的报告。

Cross-Origin-Embedder-Policy: require-corp; report-to="coep"

COEP 也支持仅报告模式,因此您可以接收报告,而无需实际阻止加载资源。

Cross-Origin-Embedder-Policy-Report-Only: require-corp; report-to="coep"

支持的浏览器

浏览器支持

  • Chrome: 83.
  • Edge: 83.
  • Firefox: 79.
  • Safari: 15.2.

来源

了解更多

HTTP 严格传输安全 (HSTS)

通过纯 HTTP 连接进行的通信未加密,这使得传输的数据可以被网络级窃听者访问。

Strict-Transport-Security 标头通知浏览器,它绝不应使用 HTTP 加载站点,而应改用 HTTPS。设置后,浏览器将在标头中定义的持续时间内使用 HTTPS 而不是 HTTP 访问域,而无需重定向。

用法示例

Strict-Transport-Security: max-age=31536000
如何使用 HSTS

当收到 HTTP 请求时,所有从 HTTP 转换为 HTTPS 的网站都应使用 Strict-Transport-Security 标头进行响应。

Strict-Transport-Security: max-age=31536000

支持的浏览器

浏览器支持

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 7.

来源

了解更多

延伸阅读