WebSub

W3C 推荐标准

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/REC-websub-20260602/
最新发布版本:
https://www.w3.org/TR/websub/
最新编辑草案:
https://w3c.github.io/websub/
历史:
https://www.w3.org/standards/history/websub/
测试套件:
https://websub.rocks/
实现报告:
https://websub.net/implementation-reports
编辑:
Julien Genestoux (邀请专家)
Aaron Parecki (邀请专家)
作者:
Julien Genestoux
反馈:
public-socialweb@w3.org 主题行使用 [websub] … 消息主题 …归档
勘误:
存在勘误
过往作者
Brad Fitzpatrick
Brett Slatkin
Martin Atkins
代码仓库
GitHub
议题
提交

另请参阅 翻译


摘要

WebSub 提供了一种通用机制,用于在任何类型 Web 内容的发布者及其 订阅者之间基于 HTTP Webhook 进行通信。订阅请求会通过中心进行中继,中心会验证并 核验该请求。然后,当新的和更新的内容可用时,中心会将其分发给订阅者。 WebSub 以前称为 PubSubHubbub。

本文档的状态

本节描述了本文档在其发布时的状态。当前 W3C 出版物列表以及本技术报告的最新修订版可在 W3C 标准与草案 索引中找到。

此更新后的规范在安全注意事项一节中加入了与跨站脚本(XSS)风险相关的缓解措施, 并致谢了报告该问题的人员。

本文档由 Social Web Working Group 作为 推荐标准并使用 推荐标准 轨道发布。

W3C 推荐将本规范作为 Web 的 标准进行广泛部署。

W3C 推荐标准是一种规范,它经过广泛的 共识构建后,由 W3C 及其成员背书,并且 获得工作组成员对实现作出的 免版税许可 承诺。

本文档由一个根据 W3C 专利 政策 运作的小组制作。 W3C 维护着一个 与该小组交付物相关的任何专利披露的公开列表; 该页面还包含 披露专利的说明。实际知晓某项专利,且认为该专利包含 必要权利要求 的个人,必须根据 W3C 专利政策第 6 节 披露相关信息。

本文档受 2025 年 8 月 18 日 W3C 流程文档 管辖。

1. 定义

主题
一个 HTTP [RFC7230] (或 HTTPS [RFC2818])资源 URL。可以订阅其变更的单元。
中心 (“该中心”)
实现此协议两端的服务器(URL [URL])。任何中心MAY 实现其自己的关于谁可以使用它的策略。
发布者
主题的所有者。当主题 feed 已更新时通知中心。与几乎所有发布订阅 系统一样,发布者并不知道订阅者(如果有)是谁。其他发布订阅系统可能会把 发布者称为“源”。
订阅者
希望被通知某个主题上变更的实体(人或程序)。订阅者必须能够被 直接通过网络访问,并由其订阅者回调 URL 标识。
订阅
订阅者与某个主题之间的一种唯一关系,表示它应接收该主题的更新。 订阅的唯一键是元组(主题 URL,订阅者回调 URL)。订阅可能(由 中心决定)具有类似于 DHCP 租约的过期时间,且必须定期续订。
订阅者 回调 URL
订阅者希望在其中接收内容分发请求的 URL [URL]。
事件
导致多个主题更新的事件。对于发生的每个事件(例如“Brad 发布到了 Linux 社区。”),可能会影响多个主题(例如“Brad 发布了内容。”以及“Linux 社区有新 帖子”)。发布者事件会导致主题被更新,中心会查找所有受影响 主题的订阅,并将内容递送给订阅者。
内容 分发通知 / (内容 分发请求)
描述某个主题内容如何发生变更的负载,或完整的更新后内容。根据 主题的内容类型,差异(或“增量”)可以由中心计算并发送给所有 订阅者。

2. 高层协议流程

(本节是非规范性的。)

WebSub 流程 图 订阅者 发布者 中心 订阅者发现发布者的 中心 主题所通告的 主题 订阅者向 中心 发出 POST,以订阅有关 主题 的更新 中心用 GET 验证订阅尝试 发布者通知 中心 有新内容 中心将 主题的内容通过 POST 递送给每个订阅者

此协议的较早版本称为 PubSubHubbub:

3. 一致性

本文档中的关键词 "MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、 "SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY" 和 "OPTIONAL" 应按 [RFC2119] 中所述解释。

3.1 一致性

除标记为非规范性的章节外,本规范中的所有编写指南、图表、示例和注释 都是非规范性的。本规范中的其他所有内容都是规范性的。

本文档中的关键词 MAYMUSTMUST NOTOPTIONALRECOMMENDEDREQUIREDSHALLSHALL NOTSHOULDSHOULD NOT 应按 BCP 14 [RFC2119] [RFC8174] 中所述解释,但仅当它们像此处所示那样全部以 大写字母出现时才如此。

3.1.1 一致性类别

WebSub 描述了三种角色:发布者、订阅者和中心。本节描述 每个角色的一致性准则。

3.1.1.1 发布者
  • 一致的发布者MUST发现 中所述,为 给定的资源 URL 通告主题和中心 URL。
3.1.1.2 订阅者

一致的订阅者:

  • MUST 按指定顺序支持每种发现机制,以 按 发现 中所述发现主题和中心 URL。
  • MUST订阅者发送订阅请求 中所述发送订阅请求。
  • MAY 请求特定的租约持续时间
  • MAY 在订阅请求中包含一个秘密值,如果这样做, 则MUST 使用该秘密值来验证内容分发请求中的签名。
  • MUST 用 HTTP 2xx 状态码确认内容分发请求。
  • MAY 请求使用 "unsubscribe" 机制停用某个订阅。
3.1.1.3 中心

一致的中心:

  • MUST 接受带有参数 hub.callbackhub.modehub.topic 的订阅请求。
  • MUST 接受带有 hub.secret 参数的订阅请求。
  • MAY 遵循订阅请求中所请求的租约持续时间。
  • MUST 允许订阅者重新请求已激活的订阅。
  • MUST 支持取消订阅请求。
  • MUST 发送具有与主题 URL 相匹配的内容 类型的内容分发请求。(见内容协商
  • MAY内容 分发 中所述,对受支持格式将内容分发的负载缩减为内容的差异。
  • MUST 在订阅使用 hub.secret 创建时发送 X-Hub-Signature 标头,如经认证的内容分发中所述。

3.2 候选 推荐退出准则

本规范在每个特性至少具有两个独立且可互操作的实现后退出 CR 阶段。 每个特性可以由不同的一组产品实现。不要求所有特性必须由单一产品实现。 为了此准则的目的,我们定义以下术语:

3.2.1 发布者

WebSub 发布者是在一个或多个资源 URL 上通告主题和中心 URL 的实现。一致性准则见上文一致性 类别

3.2.2 订阅者

WebSub 订阅者是这样一种实现:给定资源 URL 时发现中心和主题 URL, 在中心订阅更新,并接受来自中心的内容分发请求。该 订阅者MAY 支持经认证的内容分发。其 一致性准则见上文一致性类别

3.2.3 中心

WebSub 中心是处理订阅请求并在相应主题 URL 已更新时将内容分发给 订阅者的实现。中心MUST 支持带有秘密值的订阅请求,并在被请求时递送经认证的请求。中心MUST 在请求中递送主题 URL 的完整内容,并且MAY 在内容类型支持时将负载缩减为差异。其 一致性准则见上文一致性类别

3.2.4 独立

每个实现必须由不同的一方开发,且不能共享、复用或派生自 另一个合格实现所使用的代码。与本规范实现无关的代码部分 不受此要求约束。

3.2.5 可互操作

当中心执行订阅者所请求的已定义动作,订阅者根据该特性从中心获得预期响应, 并且中心向订阅者发送预期响应时,订阅者和中心实现 被认为在某个特性上是可互操作的。

3.2.6 特性

为了评估退出准则,以下每一项都被视为一项特性:

  • 通过查看资源 URL 的 HTTP 标头发现中心和主题 URL。
  • 通过将资源 URL 的内容作为 XML 文档查看来发现中心和主题 URL。
  • 通过将资源 URL 的内容作为 HTML 文档查看来发现中心和主题 URL。
  • 使用回调 URL 向中心订阅。
  • 向中心订阅并请求特定的租约持续时间。
  • 使用秘密值向中心订阅,并处理经认证的内容分发。
  • 通过发送取消订阅请求,来请求停用某个订阅。
  • 订阅者在验证请求中确认待处理的订阅。
  • 订阅者因无效的主题 URL 而拒绝订阅验证请求。
  • 当负载被递送时,订阅者返回 HTTP 2xx 响应。
  • 订阅者验证经认证的内容分发请求的签名。
  • 如果签名未通过验证,订阅者拒绝分发请求。
  • 如果订阅是使用秘密值创建的,而没有出现签名,则订阅者拒绝分发请求。
  • 中心在订阅请求期间遵循所请求的租约持续时间。
  • 中心允许订阅者重新请求已激活的订阅,从而延长租约 持续时间。
  • 中心在分发请求中发送主题 URL 的完整内容。
  • 中心为支持差异的格式发送主题 URL 的差异。
  • 中心为使用秘密值创建的订阅发送有效签名。

4. 发现

发现机制旨在识别至少 2 个 URL。

发布者可能希望通告并发布到多个中心,以实现容错和 冗余。如果一个中心未能将更新传播到文档,则使用多个独立 中心是提高向订阅者递送可能性的一种方式。因此,订阅者可以订阅 一个或多个所通告的中心。

该协议当前支持以下发现机制。发布者MUST 实现其中至少一种:

由于 <link> 多年来一直被限制为放在 <head> 中,一些消费代码可能只检查 <head>。因此,更稳健的做法是只将 <link> 标签放在 HTML <head> 中,而不是放在 <body> 中。

GET /feed HTTP/1.1
Host: example.com

HTTP/1.1 200 Ok
Content-type: text/html
Link: <https://hub.example.com/>; rel="hub"
Link: <http://example.com/feed>; rel="self"

<!doctype html>
<html>
  <head>
    <link rel="hub" href="https://hub.example.com/">
    <link rel="self" href="http://example.com/feed">
  </head>
  <body>
    ...
  </body>
</html>

执行发现时,订阅者MUST 按以下顺序实现这 两种发现机制,并在首次匹配时停止:

  1. 发出 GET 或 HEAD 请求以获取主题 URL。订阅者MUST 首先检查 HTTP Link 标头。
  2. 在没有 HTTP Link 标头的情况下,并且如果主题是基于 XML 的 feed 或 HTML 页面,订阅者 MUST 检查嵌入式 link 元素。

4.1 内容协商

出于实际目的,rel=self URL 只提供单一 表示很重要。由于中心无法知道订阅者在发现时请求了什么媒体类型([RFC6838])或语言, 因此它将无法使用文档的适当表示来递送内容。

但是,可以通过根据初始发现请求中使用的 HTTP 标头返回适当的 rel=self URL 来执行内容协商。例如,带有包含 application/jsonAccept 标头对 /feed 的请求,可以返回 /feed.json 作为 rel=self 值。

下面的示例说明了主题 URL 如何根据所发送的 Accept 标头返回不同的 Link 标头。

GET /feed HTTP/1.1
Host: example.com
Accept: application/json

HTTP/1.1 200 Ok
Content-type: application/json
Link: </feed.json>; rel="self"
Link: <https://hub.example.com/>; rel="hub"

{
  "items": [...]
}
GET /feed HTTP/1.1
Host: example.com
Accept: text/html

HTTP/1.1 200 Ok
Content-type: text/html
Link: </feed.html>; rel="self"
Link: <https://hub.example.com/>; rel="hub"

<html>
...

类似地,也可以使用该技术,根据 Accept-Language 标头所请求的语言返回不同的 rel=self URL。

GET /feed HTTP/1.1
Host: example.com
Accept-Language: de-DE

HTTP/1.1 200 Ok
Content-type: application/json

Link: </feed-de.json>; rel="self"
Link: <https://hub.example.com/>; rel="hub"

{
  "items": [...]
}

5. 订阅和取消订阅

订阅主题 URL 由四个部分组成,这些部分可以立即按顺序发生,也可以存在延迟。

取消订阅以相同方式工作,只是会更改一个参数以表明 取消订阅的意愿。另外,中心不会与发布者一起验证取消订阅请求。

5.1 订阅者发送 订阅请求

订阅由订阅者向中心 URL 发出 HTTPS 或 HTTP POST [RFC7231] 请求来发起。此请求MUST 具有 application/x-www-form-urlencoded 的 Content-Type 标头(见 [HTML5] 第 4.10.22.6 节),MUST 使用 UTF-8 [Encoding] 作为文档字符 编码,并且MUST 在其主体中使用以下参数,并按相应格式设置:

hub.callback
REQUIRED。应递送内容分发 通知的订阅者回调 URL。回调 URL SHOULD 是 每个订阅唯一且不可猜测的 URL。([capability-urls])
hub.mode
REQUIRED。字面字符串 "subscribe" 或 "unsubscribe",取决于 请求的目标。
hub.topic
REQUIRED。订阅者希望订阅或 取消订阅的主题 URL。注意,这MUST 是在 发现步骤期间找到的 "self" URL,它可能不同于用于发出发现请求的 URL。
hub.lease_seconds
OPTIONAL。订阅者希望 订阅保持活动状态的秒数,以正十进制整数给出。中心MAY 选择 是否遵循此值,具体取决于其自身策略,并且MAY 在 订阅者省略该参数时设置默认值。此参数MAY 出现在取消订阅请求中,而在这种情况下中心MUST 忽略它。
hub.secret
OPTIONAL。订阅者提供的加密随机唯一秘密 字符串,它将用于为授权内容分发计算 HMAC 摘要。如果未提供, 则内容分发请求中不会出现 HMAC 摘要。此参数SHOULD 仅在请求通过 HTTPS [RFC2818] 发出时指定。此参数MUST 小于 200 字节长度。

订阅者MAY 还包含其他 HTTP [RFC7230] 请求参数,以及中心所需的 HTTP [RFC7230] 标头。

中心MUST 忽略它们不理解的其他请求参数。

中心MUST 允许订阅者重新请求已经 激活的订阅。随后每次向中心发出的订阅或取消订阅请求MUST 覆盖特定主题 URL 和回调 URL 组合的先前订阅状态,但前提是 该动作已被验证(第 4.3 节)。如果验证失败, 订阅状态MUST 保持不变。这是必需的,以便订阅者可以 在租约秒数期限结束之前续订其订阅,而不会出现任何中断。该 订阅者MAY 在将来的订阅中使用新的 hub.secret 值,并且MAY 在没有 hub.secret 的情况下创建新的订阅。

5.1.1 订阅参数 详细信息

主题和回调 URL MAY 使用 HTTP [RFC7230] 或 HTTPS [RFC2818] 方案。主题 URL MUST 是发布者在发现阶段通过 Self Link Header 通告的那个。 (见第 3 节)。如果主题 URL 与发布者通告的 URL 不对应, 中心MAY 拒绝订阅。除此之外,主题 URL 可以按照 URL 规范 [URL] 自由形式给出。中心MUST 始终对这些 URL 参数中的非保留字符进行解码;见 [URL] 中关于“百分号编码字节”的第 1.2 节。

回调 URL SHOULD 是不可猜测的唯一 URL([capability-urls]),并且SHOULD 使用 HTTPS [RFC7230]。 在确认订阅和递送内容时,回调 URL 充当从中心到订阅者的认证。 此外,回调SHOULD 是唯一的 (不为多个中心重复使用),并在续订订阅时更改。

回调 URL MAY 包含任意查询字符串参数(例如 ?foo=bar&red=fish)。中心MUST 在订阅验证期间保留查询字符串, 方法是使用 &(和号)字符连接,将新参数追加到列表末尾。 名称与验证请求所使用名称重叠的现有参数不会被覆盖。发送内容分发 请求时,中心将向回调 URL 发出 POST 请求,并在请求的 URL 部分包含任何查询字符串参数, 而不是作为 POST 主体参数。

5.1.2 订阅响应 详细信息

如果中心 URL 支持 WebSub,并且能够处理订阅或取消订阅请求,则它 MUST 以 HTTP [RFC7231] 202 "Accepted" 响应来响应订阅请求,以表明该请求已被接收,并将由中心进行 验证(第 5.3 节)和校验(第 5.2 节)。中心SHOULD 尽快执行意图的验证和校验。

如果中心在订阅请求中发现任何错误,则MUST 返回适当的 HTTP [RFC7231] 错误响应码(4xx 或 5xx)。发生错误时,中心SHOULD 在响应主体中以纯文本形式返回错误描述,用于帮助客户端开发者理解错误。 这并非旨在显示给最终用户。中心MAY 根据其自身策略 决定拒绝某些回调 URL 或主题 URL(例如,域授权、主题 URL 端口号)。 但是,由于意图的验证和校验是异步步骤,其逻辑上在 HTTP 响应返回之后开始, 因此 HTTP 响应MUST NOT 依赖于验证或校验的过程或结果。

如果中心 URL 无法处理订阅或取消订阅请求,它MAY 重定向到另一个支持 WebSub 的中心。它通过产生 HTTP [RFC7231] 307(临时重定向)或 308(永久重定向)响应来这样做。它MUST 还 至少包含一个 HTTP [RFC7230] Location 标头,其中包含订阅者要使用的中心的首选 URL 引用。 订阅者预期会在新的中心 URL 重试订阅或取消订阅。

5.2 订阅校验

订阅MAY 由中心进行校验,中心可能需要更多详细信息来 接受或拒绝订阅。中心MAY 还会与发布者核对 是否应接受该订阅。

如果(以及当)订阅被接受,中心MUST 执行订阅者的意图验证

如果(以及当)订阅被拒绝,中心MUST 通过向订阅请求中给出的 订阅者回调 URL 发送 HTTP [RFC7231](或 HTTPS [RFC2818])GET 请求来通知订阅者。此请求附加以下查询字符串参数 (格式见 [URL] 第 4 节):

hub.mode
REQUIRED。字面字符串 "denied"。
hub.topic
REQUIRED。相应订阅请求中给出的主题 URL。
hub.reason
OPTIONAL。中心可以包含订阅被拒绝的原因。

订阅MAY 在任何时候被中心拒绝(即使它之前已被 接受)。订阅者SHOULD 随后认为该订阅 不再可能。

5.3 中心验证 订阅者的意图

为了防止攻击者代表订阅者创建不想要的订阅(或 取消订阅所需的订阅),中心必须确保订阅者确实发送了订阅 请求。

中心通过向订阅请求中给出的订阅者回调 URL 发送 HTTP [RFC7231](或 HTTPS [RFC2818])GET 请求来验证订阅请求。 此请求附加以下查询字符串参数(格式见 [URL] 第 4 节):

hub.mode
REQUIRED。字面字符串 "subscribe" 或 "unsubscribe",它与订阅者向中心发出的原始请求相匹配。
hub.topic
REQUIRED。相应订阅请求中给出的主题 URL。
hub.challenge
REQUIRED。由中心生成的随机字符串,订阅者MUST 回显它以验证订阅。此随机字符串MUST 仅由以下集合中的字符组成: [#x2B] | [#2D-#x39] | [#x3D] | [#41-#x5A] | [#x5F] | [#x61-#x7A]
hub.lease_seconds
REQUIRED/OPTIONAL。由中心确定的秒数, 表示订阅在过期前保持活动的时间,从中心向订阅者发出 验证请求的时间开始计算。当 hub.mode 设置为 "subscribe" 时,中心MUST 提供此参数。当 hub.mode 为 "unsubscribe" 时,此参数MAY 存在,并且在这种情况下订阅者MUST 忽略它。

5.3.1 验证详细信息

订阅者MUST 确认 hub.topic 对应于它希望执行的 待处理订阅或取消订阅。如果是,则订阅者MUST 以 HTTP 成功(2xx)代码响应,并使响应主体等于 hub.challenge 参数。如果订阅者不同意该动作,则 订阅者MUST 以 404 "Not Found" 响应进行响应。

订阅者MUST 为订阅确认 响应使用安全媒体类型,以防止反射式代码注入(反射式 XSS)攻击。

中心MUST 将其他服务器响应码(3xx、4xx、5xx)视为 验证请求失败。如果订阅者返回 HTTP [RFC7231] 成功(2xx),但内容主体与 hub.challenge 参数不匹配,则中心 MUST 也认为验证失败。

中心MAY 使 hub.lease_seconds 等于 订阅者在其订阅请求中传递的值,但MAY 根据 中心策略更改该值。为了维持订阅,订阅者MUSThub.lease_seconds 秒经过之前,在中心重新请求订阅。

中心MUST 强制执行租约过期,并且MUST NOT 发出永久租约持续时间。

本规范使用 GET 与 POST 来区分订阅请求的确认/拒绝 和内容递送。虽然从 Web 架构角度看,这不被认为是“最佳实践”, 但它确实使回调 URL 的实现更简单。由于内容 分发请求的 POST 主体可以是任意内容类型,并且只包含文档的实际内容, 因此使用 GET 与 POST 的区别在这两种模式之间切换处理,可使 实现更简单。

6. 发布

当主题已更新时,发布者MUST 通知其先前指定的中心。 中心和发布者可以约定任何机制,只要中心最终能够将 更新后的负载发送给订阅者即可。

发布者通知中心的具体机制留待未指定。例如, 一些现有公共中心 [1] [2] [3] 要求发布者发送带有键 hub.mode="publish"hub.url=(已更新资源的 URL) 的 POST 请求。

6.1 订阅迁移

如果发布者希望将现有订阅迁移到新的主题 URL,它可以使用 HTTP 重定向来做到这一点。

这不需要先前中心的任何参与,并且无论发布者是否也更换中心都适用。

7. 内容分发

当某个主题 URL 有新内容可用时,中心会向订阅者发送内容分发请求。 该请求是从中心到订阅者回调 URL 的 HTTP [RFC7231](或 HTTPS [RFC2818])POST 请求。 POST 请求的 HTTP 主体MUST 包含内容 分发通知的负载。内容分发请求MUST 具有 与主题的 Content-Type 对应的 Content-Type 标头,并且MUST 包含主题 URL 的完整内容,但允许如下所述的例外。

对于 Atom([RFC4287])和 RSS([RSS-2.0])feed,中心MAY 从 feed 中移除已经递送过的 atom:entryrss:item 元素。

该请求MUST 包含至少一个 Link 标头 [RFC5988],其 rel=hub 指向与正在更新的主题相关联的中心。它MUST 还包含一个 Link 标头 [RFC5988],其 rel=self 设置为 正在更新的主题的规范 URL。中心SHOULD 将这些标头合并为 一个 Link 标头 [RFC5988]。所有这些 URL 都是发现 过程(第 3 节)产生的 URL。订阅者MUST NOT 使用这些 Link 标头来识别与内容分发请求对应的订阅,因为 Link 标头是与主题内容相关联的元数据,而不是与任何特定订阅相关联。 例如,内容分发请求中的主题 URL 可能不同于最初订阅的主题 URL。

订阅者的回调 URL MUST 返回 HTTP [RFC7231] 2xx 响应码以表示成功。订阅者的回调 URL MAY 返回 HTTP 410 代码以表示订阅已被删除,并且如果中心收到该代码作为响应,中心MAY 终止该订阅。中心MUST 将所有其他订阅者响应码视为失败;这意味着订阅者MUST NOT 使用 HTTP 重定向来移动订阅。订阅者SHOULD 尽快响应内容分发请求;其成功响应码SHOULD 仅表示已收到消息,而不是确认订阅者已成功处理该消息。 来自订阅者的响应主体MUST 被中心忽略。中心SHOULD 在其自行施加的重试次数和总体重试时间限制内, 重试内容分发请求。 当失败的递送超出中心的限制时,中心会停止尝试递送该通知。中心 MUST 使订阅保持活动直到租约持续时间结束,并且如果 主题发布了新的更新,则MUST 继续尝试向 先前失败的订阅者重新递送。

7.1 经认证的内容分发

如果订阅者在其订阅请求中为 hub.secret 提供了值,则中心MUST 生成负载的 HMAC 签名,并将该签名包含在 内容分发请求的请求标头中。X-Hub-Signature 标头的值 MUST 采用 method=signature 形式,其中 method 是 可识别的算法名称之一,而 signature 是签名的十六进制表示。 签名MUST 使用 HMAC 算法 [RFC6151] 计算,其中请求主体作为数据,hub.secret 作为密钥。

7.1.1 可识别的算法名称

以下算法是最初注册的算法名称,基于发布时 [FIPS-PUB-180-4] 注册表的内容。

sha1
[FIPS-PUB-180-4] 第 6.1 节中指定的 SHA-1 算法
sha256
[FIPS-PUB-180-4] 第 6.2 节中指定的 SHA-256 算法
sha384
[FIPS-PUB-180-4] 第 6.5 节中指定的 SHA-384 算法
sha512
[FIPS-PUB-180-4] 第 6.4 节中指定的 SHA-512 算法

将来,可能会指定一个扩展,允许订阅者指明其 可用于验证的算法。在撰写本文时,大多数中心使用 SHA-1 进行签名,尽管它存在已知的 密码学弱点,但这样做是为了与较旧的订阅者互操作。

7.1.2 签名验证

当订阅者接收到指定了 X-Hub-Signature 标头的内容分发请求时, 它们SHOULD 使用共享秘密值,并使用与中心相同的方法 (在 X-Hub-Signature 标头中提供)重新计算签名。如果签名 不匹配,订阅者MUST 在本地将该消息作为无效消息忽略。 订阅者MAY 仍然以 2xx 响应码确认此请求, 以便能够异步处理消息和/或防止对 签名的暴力尝试。将此技术与用于订阅请求的 HTTPS [RFC2818] 结合使用, 可使简单订阅者从中心接收经认证的内容分发请求,而无需 订阅者运行 HTTPS [RFC2818] 服务器。

不过请注意,该签名仅确保负载未被伪造。由于 请求还包含标头,除非订阅者使用 HTTPS [RFC2818] 回调, 否则订阅者不应将这些标头视为安全。

8. 安全注意事项

以下是安全注意事项的摘要。需要注意的是,WebSub 是一种服务器到服务器 协议,仅依赖 HTTP。强烈建议对所有请求使用 HTTPS。

8.1 发现

订阅者是否应在页面的 <body> 内部(以及 <head> 内部)查找 <link> 元素,这一决定并不简单, 目前也没有明确共识。在发现期间忽略 <body> 的一个原因是, 某些网站可能(也许是意外地)允许用户发布包含 <link> 元素的内容,尽管工作组不知道任何此类网站的具体示例。 如果 WebSub 发现使用这样的 <link> 元素,那么向 此类网站贡献内容的用户可能会恶意地使所有订阅者使用备用中心,而该中心之后 递送恶意内容。鉴于这种潜在攻击,只在 HTML 文档的 <head> 中执行发现可能更为谨慎。

8.2 订阅

首先,订阅者SHOULD 始终优先使用中心的 HTTPS URL(即使该 URL 被通告为 HTTP)。其次,订阅者SHOULD 为回调使用唯一且不可猜测的 capability URL,并使它们可通过 HTTPS 访问。最后,订阅者SHOULD 在订阅时使用 hub.secret,以允许对 内容分发进行签名。

中心SHOULD 强制执行短期的 hub.lease_seconds(10 天是一个 良好的默认值)。执行意图验证时,中心SHOULD 使用 随机的一次性 hub.challenge

意图验证过程会引入反射式代码注入(反射式 XSS)攻击的风险。 订阅者MUST 使用安全媒体类型 (例如 application/octet-stream)提供意图验证响应, 以防止此类攻击。此外,意图验证响应可能被利用来绕过 Content-Security-Policy 限制:订阅者MUSTX-Content-Type-Options: nosniff 提供意图验证响应,以缓解这种风险。

意图验证过程可能被用于欺骗用户从受信任的订阅者下载恶意资源。 订阅者SHOULDhub.challenge 参数施加限制,例如限制其长度并拒绝二进制数据。

8.3 分发

中心MUST 使用订阅者所使用的确切回调(包括使用 HTTPS)。如果被请求,中心MUST 使用订阅者提供的 hub.secret 对其请求进行签名。

如果订阅者在订阅请求中包含了 hub.secret,则订阅者SHOULD 验证中心提供的签名;如果它们这样做,则它们MUST 使用服务器所声明的签名机制,并丢弃 未通过测试的请求。

如果订阅者未使用安全回调 URL(HTTPS),或者怀疑中心与订阅者之间的 TLS 传输 可能已被破坏,那么内容递送 通知的完整性仅由 hub.secret 和所使用的散列算法保护。在这种 情况下,应根据应用程序的安全要求使用适当的散列算法。 由于截至本文档发布日期 SHA-1 已被证明遭到破坏,因此 至少应使用 SHA-256。

8.4 安全与隐私审查

这些问题提供了本规范的安全与隐私注意事项概览,其依据是 Self-Review Questionnaire: Security and Privacy([security-privacy-questionnaire])的指导。

本规范是否处理个人可识别信息?
涉及的唯一潜在个人可识别信息是主题 URL 和回调 URL。
本规范是否处理高价值数据?
否,不涉及认证或其他凭证。
本规范是否为源引入跨浏览会话持久存在的新状态?
否。
本规范是否向 Web 暴露持久的跨源状态?
WebSub 订阅者应创建一个包含其所订阅主题相关信息的资源。
本规范是否向某个源暴露其当前无权访问的任何其他数据?
否。
本规范是否启用新的脚本执行/加载机制?
否。
本规范是否允许源访问用户的位置?
否。
本规范是否允许源访问用户设备上的传感器?
否。
本规范是否允许源访问用户本地计算环境的各个方面?
否。
本规范是否允许源访问其他设备?
否。
本规范是否允许源对用户代理的原生 UI 进行某种程度的控制?
否。
本规范是否向 Web 暴露临时标识符?
否。
本规范是否区分第一方和第三方上下文中的行为?
否。
本规范在用户代理的“隐身”模式上下文中应如何工作?
WebSub 是服务器到服务器协议,其中“隐身”模式没有意义。
本规范是否将数据持久化到用户的本地设备?
否。
本规范是否允许降低默认安全特性?
否。

A. 致谢

本节是非规范性的。

编辑感谢 PubSubHubbub 的作者、IndieWeb 社区以及其他实现者的 支持、鼓励和热情。特别是,编辑感谢 Brad FitzpatrickBrett SlatkinMartin AtkinsAmy GuyBarry FrostBenjamin RobertsEugen RochkoJordan PotterMatthias PfefferleMalcolm BlaneyMarten de VriesSandro HawkeTantek Çelik、 以及 Tony Garnock-Jones

W3C 团队感谢 Gabriel Corona 报告 XSS

B. 变更日志

本节是非规范性的。

B.1 从 2017 年 10 月 03 日 PR 到此版本的变更

B.2 从 2017 年 4 月 11 日 CR 到 2017 年 10 月 03 日 PR 的变更

B.3 从 2017 年 11 月 24 日 WD 到 2017 年 4 月 11 日 CR 的变更

B.4 从 10 月 20 日 FPWD 到 2016 年 11 月 24 日的变更

C. 参考文献

C.1 规范性参考文献

[capability-urls]
Capability URL 的良好实践。Jeni Tennison。W3C。2014 年 2 月 18 日。FPWD。URL:https://www.w3.org/TR/capability-urls/
[Encoding]
编码标准。Anne van Kesteren。 WHATWG。Living Standard。URL:https://encoding.spec.whatwg.org/
[FIPS-PUB-180-4]
安全散列标准(SHS)。 National Institute of Standards and Technology。U.S. Department of Commerce。URL:http://dx.doi.org/10.6028/NIST.FIPS.180-4
[HTML5]
HTML5。Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Theresa O'Connor; Silvia Pfeiffer。W3C。2018 年 3 月 27 日。W3C 推荐标准。URL:https://www.w3.org/TR/html5/
[PubSubHubbub-Core-0.3]
PubSubHubbub Core 0.3 -- 工作草案。B. Fitzpatrick; B. Slatkin; M. Atkins。URL:https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.3.html
[PubSubHubbub-Core-0.4]
PubSubHubbub Core 0.4 -- 工作草案。B. Fitzpatrick; B. Slatkin; M. Atkins; J. Genestoux。 URL:https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html
[RFC2119]
RFC 中用于指示 要求级别的关键词。S. Bradner。IETF。1997 年 3 月。Best Current Practice。URL:https://www.rfc-editor.org/rfc/rfc2119
[RFC2818]
TLS 上的 HTTP。E. Rescorla。IETF。 2000 年 5 月。Informational。URL:https://httpwg.org/specs/rfc2818.html
[RFC4287]
Atom 聚合格式。M. Nottingham, Ed.; R. Sayre, Ed. IETF。2005 年 12 月。Proposed Standard。URL:https://www.rfc-editor.org/rfc/rfc4287
[RFC5988]
Web Linking。M. Nottingham。IETF。 2010 年 10 月。Proposed Standard。URL:https://www.rfc-editor.org/rfc/rfc5988
[RFC6151]
MD5 消息摘要和 HMAC-MD5 算法的更新安全注意事项。S. Turner; L. Chen。IETF。2011 年 3 月。 Informational。URL:https://www.rfc-editor.org/rfc/rfc6151
[RFC6838]
媒体类型规范和注册 程序。N. Freed; J. Klensin; T. Hansen。IETF。2013 年 1 月。Best Current Practice。URL:https://www.rfc-editor.org/rfc/rfc6838
[RFC7230]
超文本传输协议(HTTP/1.1): 消息语法和路由。R. Fielding, Ed.; J. Reschke, Ed. IETF。2014 年 6 月。 Proposed Standard。URL:https://httpwg.org/specs/rfc7230.html
[RFC7231]
超文本传输协议(HTTP/1.1): 语义和内容。R. Fielding, Ed.; J. Reschke, Ed. IETF。2014 年 6 月。 Proposed Standard。URL:https://httpwg.org/specs/rfc7231.html
[RFC8174]
RFC 2119 关键词中大写与小写的歧义。B. Leiba。IETF。2017 年 5 月。Best Current Practice。URL:https://www.rfc-editor.org/rfc/rfc8174
[RSS-2.0]
RSS 2.0。Dave Winer。RSS Board。 Stable。URL:http://www.rssboard.org/rss-specification
[security-privacy-questionnaire]
自审问卷: 安全与隐私。Theresa O'Connor; Peter Snyder; Simone Onofri。W3C。2025 年 4 月 18 日。W3C 工作组说明。URL:https://www.w3.org/TR/security-privacy-questionnaire/
[URL]
URL 标准。Anne van Kesteren。WHATWG。 Living Standard。URL:https://url.spec.whatwg.org/