Skip to main content

2. X-Frame-Options Header (X-Frame-Options 头字段)

2. X-Frame-Options Header (X-Frame-Options 头字段)

X-Frame-Options HTTP 头字段指示了一项策略, 该策略规定浏览器是否应该在 <frame><iframe> 中渲染所传输的资源。服务器可以在其 HTTP 响应的头部中声明此策略, 以防止点击劫持 (clickjacking) 攻击, 从而确保其内容不会被嵌入到其他站点中。

2.1 Syntax (语法)

头字段名称为:

X-Frame-Options

该头字段有三种不同的值。这些值是互斥的; 也就是说, 该头字段必须被设置为这三种值中的一种。

DENY

浏览器接收到带有此头字段的内容后, 绝对不能在任何框架中显示该内容。

SAMEORIGIN

浏览器接收到带有此头字段的内容后, 绝对不能在与该内容自身来源 (origin) 不同的页面的框架中显示该内容。如果浏览器或插件无法可靠地确定内容和框架的来源是否相同, 则必须将其视为 "DENY"。

请注意, 当前的实现对此标准的解释存在差异。在某些实现中, 仅要求顶级浏览上下文 (top-level browsing context) 的来源与使用 X-Frame-Options 指令的内容的来源相匹配; 在其他实现中, 此标准必须对所有祖先浏览上下文都满足。有关框架嵌套和不同浏览器对该头字段处理行为的差异的更多详细信息, 请参见第 2.3.2.2 节。此外, 请参考第 4 节第 2 段, 了解由此可能导致的潜在安全问题。

ALLOW-FROM (后跟一个序列化来源 (serialized-origin) [RFC6454])

浏览器接收到带有此头字段的内容后, 绝对不能在顶级浏览上下文的来源与指定来源不同的页面的框架中显示该内容。虽然此头字段值可能具有有限的支持, 但它在现代浏览器中已被弃用。

请注意, X-Frame-Options 头字段必须作为 HTTP 头字段发送, 并且浏览器会明确忽略通过 <meta http-equiv> 标签声明的该头字段。

2.2 Augmented Backus-Naur Form (ABNF) (增强巴科斯-诺尔范式)

RFC 5234 ABNF [RFC5234] 中 X-Frame-Options 头字段值的定义如下:

id-name                = "X-Frame-Options"
X-Frame-Options = "DENY"
/ "SAMEORIGIN"
/ ( "ALLOW-FROM" RWS serialized-origin )

RWS = 1*( SP / HTAB )
; required whitespace

serialized-origin = scheme "://" host [ ":" port ]
; <scheme>, <host>, <port> as per RFC 6454

其中 "serialized-origin" 定义在 RFC 6454 [RFC6454] 的第 6.2 节中。产生式 "serialized-origin" 意味着序列化的来源字符串不能包含任何空白字符。

2.2.1 Examples of X-Frame-Options (X-Frame-Options 示例)

X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM https://example.com/

2.3 Design Issues (设计问题)

2.3.1 Enable HTML Content from Other Domains (启用来自其他域的 HTML 内容)

有许多主要的直接向量可以启用来自其他域的 HTML 内容, 例如:

  • <frame> 元素
  • <iframe> 元素
  • <object> 元素
  • <applet> 元素
  • <embed> 元素

除此之外, 其他元素可能被利用在父框架中执行操作, 这可能导致类似点击劫持的攻击, 包括 <script> 标签、<form> 标签和 <button> 标签等。X-Frame-Options 头字段提供了一种机制, 站点运营者可以通过该机制指示其页面不应被嵌入到来自其他域的框架中, 从而防御点击劫持攻击。

2.3.2 Browser Behavior and Processing (浏览器行为和处理)

2.3.2.1 Violation of X-Frame-Options (违反 X-Frame-Options)

当浏览器检测到阻止页面在框架中渲染的 X-Frame-Options 头时, 浏览器必须立即停止渲染该文档。

该页面必须被视为用户已取消加载该文档的请求。这类似于用户代理处理 "204 No Content" 响应的方式, 尽管后者不会导致错误条件。

如果浏览器已经开始下载页面中包含的图像或其他资源请求, 浏览器应该尽快尝试停止下载这些资源。

2.3.2.2 Variation in Current Browser Behavior (当前浏览器行为的差异)

浏览器在使用 SAMEORIGIN 头字段时对框架和浏览上下文检查的解释存在差异。预期的行为是, 用户代理必须仅在该框架与被框架化的页面处于相同来源时才在框架中渲染该页面。

然而, 浏览器实现存在差异。一些实现遍历浏览上下文的整个祖先树, 并要求每个祖先都处于相同来源。其他实现仅验证顶级浏览上下文 (窗口) 是否来自相同来源。

这意味着, 对于通过多个中间页面 "框架化" 的页面 (即, 框架中的框架中的框架), 成功渲染的页面集可能比规范意图更严格 (在检查整个祖先链的实现中) 或更宽松 (在仅检查顶级框架的实现中)。

站点运营者应该意识到这种行为的潜在差异, 并在其预期的浏览器基础上测试渲染, 以确保符合其反点击劫持策略。

2.3.2.3 Usage Design Pattern and Example Scenario for the ALLOW-FROM Parameter (ALLOW-FROM 参数的使用设计模式和示例场景)

由于不同浏览器之间的支持较弱且实现各不相同, ALLOW-FROM 选项已被弃用。站点运营者应该考虑使用 Content Security Policy 的 frame-ancestors 指令 [CSP2] 来代替, 该指令提供了对框架嵌入策略的更好控制, 并具有更好的浏览器支持。

2.3.2.4 No Caching of the X-Frame-Options Header (不缓存 X-Frame-Options 头)

浏览器必须为每个 HTTP 响应处理 X-Frame-Options 头字段值, 而不管该 HTTP 响应中存在的缓存指令或先前缓存的响应如何。该头字段在导航时进行评估, 并且绝对不能被缓存。这确保了最新的策略得到强制执行。