Copyright © 2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
本文档定义了一种机制,使开发者能够为网页应用声明网络错误报告策略。用户代理可以利用该策略报告其在获取所请求资源时遇到的网络错误,这些错误阻止了请求的成功获取。
本节描述了本文档在发布时的状态。当前 W3C 的出版物列表和本技术报告的最新修订版可在 W3C 标准与草案索引中找到, 地址:https://www.w3.org/TR/。
本文档由 Web 性能工作组 作为 推荐标准流程 的工作草案出版。
作为工作草案发布并不代表 W3C 及其成员的认可。
本文为草案文档,可能随时被更新、替换或废弃。引用本文档应仅作为工作进展,不应作其他用途。
本文档由一在 W3C 专利政策 下运作的小组产生。 W3C 维护了 与本小组成果相关的专利公开的公开列表, 该页面同时还包含专利披露说明。若个人实际知晓某专利,且认为其包含 必要声明, 必须依照 W3C 专利政策第6节披露此信息。
本文档受 2023年11月3日 W3C 流程文件管理。
精准衡量网页应用的性能特性对于帮助网站开发者理解如何改进他们的网页应用至关重要。最糟糕的情况是,由于网络错误导致应用或某个特定资源加载失败。要解决此类故障,开发者需要用户代理协助,识别此类失败何时、何地以及为何发生。
目前,应用开发者无法获取来自终端用户的网页应用可用性实时数据。例如,如果用户因 DNS 查询失败、连接超时、连接被重置或其他原因导致页面加载失败,站点开发者无法检测和解决此问题。请注意,这类网络错误无法仅通过服务端检测,因为按定义,客户端可能根本无法成功与服务器建立连接。
现有方法(如合成监控)通过在预定的地理位置布置监控节点来提供部分解决方案,但需要额外的基础设施投入,且无法为真实终端用户提供真正全球范围内且接近实时的可用性数据。
网络错误日志(NEL)通过定义一种机制来满足这一需求,使网页应用能够声明一种报告策略,用户代理可据此为给定的源点上报网络错误。网页应用通过返回包含 NEL HTTP 响应头字段选择使用
NEL,该头描述期望的 NEL 策略。该策略指示用户代理记录对此源点的请求信息,并尝试将这些信息发送到此前使用 Reporting
API 配置的终端组。如其名所示,NEL
报告主要用于描述错误。但为了统计不同客户端群体的错误比率,也必须了解有多少成功的请求发生;这些成功请求也可通过 NEL 机制进行报告。
例如,如果用户代理因 TCP 连接被中断无法从 https://www.example.com 获取资源,用户代理会通过 Reporting API 队列如下报告:
"network-error"report_to 字段配置的终端组{
"referrer": "https://referrer.com/",
"sampling_fraction": 1.0,
"server_ip": "192.0.2.42",
"protocol": "http/1.1",
"elapsed_time": 321,
"phase": "connection",
"type": "tcp.aborted"
}
有关报告中各字段及其格式说明,请参见 5.4 生成网络错误报告;有关 NEL 注册和上报流程的更多实例,请参见 7. 示例。
本规范中除标为非规范性外,所有作者指南、图示、示例和注释均为非规范性内容。规范中其余部分均为规范性内容。
本文档中的关键词 MAY、MUST、MUST NOT、OPTIONAL、REQUIRED 及 SHOULD, 其解释见 BCP 14 [RFC2119] [RFC8174] ,仅当全部大写出现时按上述含义解释。
以祈使句出现的规范性要求(如“去除所有前导空格”或“返回 false 并终止这些步骤”)应与引导算法时所用的关键词(如“must”、“should”、“may”等)对应理解。
部分一致性要求针对属性、方法或对象提出,此类要求应理解为针对用户代理的要求。
以算法或具体步骤方式表述的一致性要求,可以采用任何实现方式,只要最终效果等价。(本规范给出的算法旨在易于理解而非追求性能。)
当 用户代理尝试通过网络为某个请求进行HTTP 网络获取资源时,就会发生一次网络请求。
如果已知用户代理处于离线状态(即 navigator.
onLine 返回
false),请求 不得产生 网络请求。
如果请求因 混合内容 或 CORS 失败被阻止,该 请求 不得产生 网络请求。任何 CORS 预检请求 必须产生它自己的 网络请求。
无论采用哪种 fetch 算法和底层应用、传输协议,服务一次 网络请求均包含以下几个阶段:
唯一必需的阶段是请求和响应传输;其他阶段对于每个 网络请求可能不是必需的。例如,用户代理本地可以缓存 DNS 结果,从而免除后续对同一域名的 DNS 解析。同样,HTTP 持久连接允许打开一个连接后为同一分区密钥的多个请求复用。但如果多个阶段依次发生,其顺序应如上。
如果用户代理能够从服务器接收有效 HTTP 响应,且该响应状态码不是 4xx 或 5xx,则此 网络请求被认为是成功的。
每个 网络错误都有一个类型,为字符串。
dnsconnectionapplication6. 预定义网络错误类型中定义了若干预定义的 网络错误类型。
网络错误报告 是一个 Reporting API 报告,用于描述 一个 网络错误。
网络错误报告 不会 暴露给 ReportingObserver。
网络错误报告不会暴露给 ReportingObserver,
因为报告只应由接收请求的服务器管理员或所有者可见。如果它们对 ReportingObserver 可见,
那么报告也将对发起者可见。对于跨源请求,这可能会泄露有关服务器网络配置的信息给其无法控制的第三方。
NEL 策略 用于指示用户代理是否要收集发往某个 网络请求的 origin 的报告,如果需要,则指定报告发送目的地。 NEL 策略 通过 HTTP 响应头 下发给用户代理。
每个 NEL 策略都有一个接收 IP 地址,即用户代理收到 NEL 策略时服务器的 IP 地址。
每个 NEL 策略有一个源点。
每个 NEL 策略有一个 子域 标志,值可为 include 或
exclude。
每个 NEL 策略有一个请求头列表(policy request headers) 和响应头列表(policy response headers),每个列表中的元素均为头名称。
每个 NEL 策略有一个 报告组,即报告将发送到的 Reporting 终端组名称。
每个 NEL 策略有一个 ttl,表示该策略有效的秒数。
每个 NEL 策略有一个 创建时间,即用户代理收到策略的时间戳。
期望服务大量流量的源点可能无法承载为其所有 网络请求生成的完整 NEL 报告。源点可定义采样率限制每个用户代理上报的 NEL 报告数量。由于成功请求通常远多于失败请求,源点可为不同情形指定不同的采样率。
每个 NEL 策略有一个 成功采样率,值在 0.0–1.0 之间。
每个 NEL 策略有一个 失败采样率,值在 0.0–1.0 之间。
合规的用户代理必须提供一个策略缓存,即用于保存 NEL 策略 的存储机制,键为 (网络分区密钥, 源点) 二元组。
此存储机制为不透明、厂商自定义且不暴露给 Web,但必须提供下列方法,供本文档定义的算法使用:
服务器可以通过 NEL 策略
以及 NEL
HTTP 响应头为其管理的 origin 定义相应策略。
NEL
响应头用于将 origin 的 NEL 策略传递给用户代理。NEL
头的 ABNF(扩展巴科斯-诺尔范式)[RFC5234] 语法如下:
NEL = json-field-value
该响应头的值按照 json-field-value 的定义作为一个 JSON 对象数组来解释。数组中的每个对象为该 origin 定义一个 NEL 策略。用户代理必须只处理数组中的第一个有效策略,忽略数组中的其余策略。
用户代理必须忽略任何未知或无效的字段或值,凡不符合本规范定义语法的均忽略。一个有效的NEL响应头必须至少包含一个符合本规范所有 “必需” 字段的对象。
为防止通过脚本攻击劫持错误上报,对于通过 meta 元素指定的 NEL头,用户代理必须忽略。NEL 策略必须通过NEL
响应头下发。
对 meta 元素的限制与 [CSP] 规范保持一致,后者同样因安全理由只允许通过 HTTP 响应头注册上报。
report_to 字段指定本 终端组(endpoint group),NEL 报告将被发送到此组。
注册 NEL 策略必须包含该字段;若仅为移除先前注册,可可选,详见 max_age。如存在,此字段值必须为字符串;其它类型则解析失败。
必需字段 max_age 指定本 NEL
策略的有效期(以秒为单位的非负整数)。其值必须为非负整数,否则解析失败。
可选字段 include_subdomains 是布尔值,用于开启本 NEL 策略对该 origin
的所有子域生效(无限深度)。若对象中不存在该字段,或其值不为 true,则此策略不作用于子域。
若需 NEL 报告能覆盖子域,应确保 Reporting 终端组也配置了 include_subdomains 为
true。否则,若 Reporting 策略未覆盖该子域,NEL 报告即使策略开启对该子域,也无法送达。
可选字段 success_fraction 定义对本 origin 的
成功 网络请求 的 NEL 报告采样率。
若值存在,必须为 [0.0, 1.0] 区间内的数字;否则解析失败。
若未配置,则用户代理不会采集成功网络请求的 NEL 报告。
可选字段 failure_fraction 定义对本 origin
失败 网络请求 的 NEL 报告采样率。若值存在,必须为
[0.0, 1.0] 区间内的数字,否则解析失败。
若未配置,用户代理将对所有失败网络请求都采集 NEL 报告。
可选字段 request_headers 定义哪些 请求头的 名称和
值 将被包含在本 origin 的 网络错误报告中。值如存在必须为字符串数组。
可选字段 response_headers 定义哪些 响应头的
名称和 值 将被包含在本 origin 的 网络错误报告中。值如存在必须为字符串数组。
给定一个 网络请求(request)及其对应的 响应(response),本算法将从中提取 NEL 策略,并据此更新 策略缓存。
Potentially Trustworthy。
NEL 的 响应头。
NEL 的 响应头的值。
max_age 字段,或该字段值不是数字,则终止。
max_age 字段值为 0,则移除 策略缓存中 origin 为
origin 的任何 NEL 策略,并跳过余下步骤。
report_to 字段,或该字段不是字符串,则终止。
success_fraction 字段,且其值不在 [0.0, 1.0]
范围,则终止。
failure_fraction 字段,且其值不在 [0.0, 1.0]
范围,则终止。
request_headers 字段,其值非数组或数组中有非字符串元素,则终止。
response_headers 字段,其值非数组或数组中有非字符串元素,则终止。
令 policy 为新建的 NEL 策略,其属性如下:
[FETCH] 中需要更明确地传递。
include_subdomains 且值为
true,则为 include,否则为 exclude
request_headers
字段值
response_headers 字段值
report_to 字段值max_age 字段值success_fraction 字段值,如无则为
0.0
failure_fraction 字段值,如无则为
1.0
给定一个 网络请求(request),本算法用于确定在 策略缓存中,应为该 网络请求生成报告采用哪个 NEL 策略。
include,则返回它。
无策略。
给定 网络请求(request)及其对应的 响应(response),如果有匹配的 NEL 策略要求报告,则本算法为 request 生成报告并返回报告及 NEL 策略,否则返回 null。
Potentially Trustworthy,返回 null。
无策略,返回 null。
phase 属性不是 dns,则附加以下属性:
phase 不是 dns 或
connection,则附加以下属性:
include,并且 report body
的 phase 不是 dns,
返回 null。
phase 不是 dns,且 report body 的
server_ip 属性非空且不等于 policy 的 接收 IP 地址:
phase 设为 dns。
type 设为 dns.address_changed。
request_headers、response_headers、status_code 和
elapsed_time 属性。
当服务器与策略的 IP 地址不匹配时,此步骤会“降级”NEL 报告,仅允许其携带 DNS 解析相关信息。这样做目的是隐私保护,确保最后只有域名持有者能收到该报告,否则不可追踪到具体服务器。详见 9. 隐私注意事项 和 7.5 多 IP 地址源站。
给定一份 ECMAScript 对象(report body,通常由 生成网络错误报告返回,随后由调用规范补充)及其匹配的 NEL 策略(policy)和 网络请求(request),本算法负责队列化报告以进行投递。
用户代理可以扩展该列表,添加自定义网络错误
类型,例如为新协议或现有协议的更详细错误描述增加支持。此时,用户代理应当遵循点分命名([group].[optional-subgroup].[error-name])格式,以便对错误报告进行一致和简化的处理——比如收集器可以按类别/子组聚合展示。
本节内所有网络错误均发生在DNS 解析阶段,故其phase为 dns。
dns.unreachabledns.name_not_resolveddns.faileddns.address_changed
本节内所有网络错误均发生在安全连接建立阶段,故其phase为 connection。
tcp.timed_outtcp.closedtcp.resettcp.refusedtcp.abortedtcp.address_invalidtcp.address_unreachabletcp.failedtls.version_or_cipher_mismatchtls.bad_client_auth_certtls.cert.name_invalidtls.cert.date_invalidtls.cert.authority_invalidtls.cert.invalidtls.cert.revokedtls.cert.pinned_key_not_in_cert_chaintls.protocol.errortls.failed
本节内所有网络错误均发生在请求和响应传输阶段,故其phase为 application。
http.errorhttp.protocol.errorhttp.response.invalidhttp.response.redirect_loophttp.failedabandonedunknown> GET / HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK
< ...
< Report-To: {"group": "network-errors", "max_age": 2592000,
"endpoints": [{"url": "https://example.com/upload-reports"}]}
< NEL: {"report_to": "network-errors", "max_age": 2592000}
该 NEL 响应头定义了一个 NEL 策略,指示用户代理将关于 example.com 的网络错误报告发送到名为
network-errors 的 终端组。该策略有效期为 2592000 秒(30 天)。
注意,上述注册仅当响应来自于潜在可信源点时才会成功。
> GET / HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK
< ...
< NEL: {"max_age": 0}
此 NEL 响应头指示用户代理移除 example.com 的所有现有 NEL 策略。
本节包含 网络错误报告的示例,当用户代理在某个已经注册了NEL 策略的 origin 上遇到网络错误时,用户代理可能会队列化这些报告。我们展示了使用 [REPORTING] API 上传时生成的完整报告载荷;载荷的 body 字段包含 网络错误报告体。
{
"age": 0,
"type": "network-error",
"url": "https://www.example.com/",
"body": {
"sampling_fraction": 0.5,
"referrer": "http://example.com/",
"server_ip": "2001:DB8:0:0:0:0:0:42",
"protocol": "h2",
"method": "GET",
"request_headers": {},
"response_headers": {},
"status_code": 200,
"elapsed_time": 823,
"phase": "application",
"type": "http.protocol.error"
}
}
该报告表示用户代理尝试从 example.com 导航到 www.example.com,其成功解析为
2001:DB8::42。但虽然用户代理从服务器通过 HTTP/2(h2)协议接收到 200
响应,却在过程中遇到协议错误,最终放弃导航。用户代理在导航开始 823 毫秒后终止导航。最后,在网络错误发生后立即发送本报告,即报告 age 为 0。
{
"age": 0,
"type": "network-error",
"url": "https://widget.com/thing.js",
"body": {
"sampling_fraction": 1.0,
"referrer": "https://www.example.com/",
"server_ip": "",
"protocol": "",
"method": "GET",
"request_headers": {},
"response_headers": {},
"status_code": 0,
"elapsed_time": 143,
"phase": "dns",
"type": "dns.name_not_resolved"
}
}
上述报告表示用户代理尝试从 https://www.example.com/ 获取 https://widget.com/thing.js,但无法解析
DNS 名称(widget.com),请求在 143 毫秒后被用户代理中止。因先前请求 widget.com 时曾下发有效 NEL 策略,本次请求产生了 网络错误报告。报告上传于错误发生后立即,即 age 为 0。
> GET / HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK
< ...
< Report-To: {"group": "network-errors", "max_age": 2592000,
"endpoints": [{"url": "https://example.com/upload-reports"}]}
< NEL: {"report_to": "network-errors", "max_age": 2592000, "include_subdomains": true}
此 NEL 响应头允许 example.com 的所有者检测 DNS 配置错误——例如遗忘添加解析
new-subdomain.example.com 到 IP 地址的新资源记录。当用户代理尝试请求 new-subdomain.example.com
时,可能会生成如下报告:
{
"age": 0,
"type": "network-error",
"url": "https://new-subdomain.example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {},
"response_headers": {},
"status_code": 0,
"elapsed_time": 48,
"phase": "dns",
"type": "dns.name_not_resolved"
}
}
> GET / HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK
< ...
< Report-To: {"group": "network-errors", "max_age": 2592000,
"endpoints": [{"url": "https://example.com/upload-reports"}]}
< NEL: {"report_to": "network-errors", "max_age": 2592000, "success_fraction": 1.0,
"request_headers": ["If-None-Match"], "response_headers": ["ETag"]}
< ETag: 01234abcd
在本例中,example.com 的所有者使用 ETag 响应头标识对应资源的不同版本。用户代理随后可使用 If-None-Match
请求头告知服务器客户端已缓存的资源版本,从而在副本有效时避免生成和下发内容。
通过让该域名的 NEL 响应头包含 request_headers 和 response_headers 字段,浏览器将在 NEL 报告中包含 If-None-Match 请求头和 ETag 响应头的副本,从而让站点所有者追踪缓存策略效果。
基于上述,考虑以下事件流程:
用户代理向 example.com 发送 请求,收到 成功响应,响应中含有 ETag。用户代理将生成如下 NEL 报告:
{
"age": 0,
"type": "network-error",
"url": "https://example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "192.0.2.1",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {},
"response_headers": {
"ETag": ["01234abcd"]
},
"status_code": 200,
"elapsed_time": 1392,
"phase": "application",
"type": "ok"
}
}
之后用户代理又发送一次 请求,本地仍有原始资源副本,并在 If-None-Match
请求头中添加其版本。服务器检查该版本仍然有效,并返回 304 响应,表示缓存依然有效。用户代理将生成如下报告:
{
"age": 0,
"type": "network-error",
"url": "https://example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "192.0.2.1",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {
"If-None-Match": ["01234abcd"]
},
"response_headers": {
"ETag": ["01234abcd"]
},
"status_code": 304,
"elapsed_time": 45,
"phase": "application",
"type": "ok"
}
}
晚些时候,用户代理再次向 example.com 发送 请求,缓存依然,与前例一样带了 If-None-Match,但服务器此时检测到有新版本,生成并下发新内容及新的
ETag,用户代理生成如下报告:
{
"age": 0,
"type": "network-error",
"url": "https://example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "192.0.2.1",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {
"If-None-Match": ["01234abcd"]
},
"response_headers": {
"ETag": ["56789ef01"]
},
"status_code": 200,
"elapsed_time": 935,
"phase": "application",
"type": "ok"
}
}
对于 origin 的 域名解析为多个 IP 地址的情况,NEL 有时会“降级”错误报告,仅保留更少的出错信息,因为用户代理无法确认 origin 的拥有者和实际 服务器的拥有者一致。
例如,假设 example.com 由三个不同 IP 地址的 服务器 负责,服务端将 DNS 解析为
192.0.2.1、192.0.2.2、192.0.2.3,并依靠用户代理对其请求进行负载均衡。服务所有者会下发如下 NEL 策略:
> GET / HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK
< ...
< Report-To: {"group": "network-errors", "max_age": 2592000,
"endpoints": [{"url": "https://example.com/upload-reports"}]}
< NEL: {"report_to": "network-errors", "max_age": 2592000,
"success_fraction": 1.0, "failure_fraction": 1.0}
基于上述,考虑如下事件序列:
用户代理向 192.0.2.1 发送 请求,收到 成功响应。响应中也包含上述 NEL
策略,用户代理将策略的 接收 IP 地址 设为 192.0.2.1。由于接收 IP 地址与服务器
IP 地址匹配(成功请求必然如此),生成如下 NEL 报告:
{
"age": 0,
"type": "network-error",
"url": "https://example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "192.0.2.1",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {},
"response_headers": {},
"status_code": 200,
"elapsed_time": 57,
"phase": "application",
"type": "ok"
}
}
用户代理再向 192.0.2.2 发送请求收到成功响应,此响应同样包含 NEL 策略,用户代理将策略的 接收 IP 地址 更新为 192.0.2.2,由于匹配,生成如下报告:
{
"age": 0,
"type": "network-error",
"url": "https://example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "192.0.2.2",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {},
"response_headers": {},
"status_code": 200,
"elapsed_time": 34,
"phase": "application",
"type": "ok"
}
}
用户代理再尝试向 192.0.2.3 发送请求,但无法建立连接。此时策略仍在 策略缓存中,理想状况下用户代理会生成 about 失败
网络请求 的 tcp.timed_out 报告。但实际上由于策略中的“接收
IP 地址” (192.0.2.2) 与本次请求实际的服务器 IP 不符,用户代理无法确认 192.0.2.3 是否归属于
example.com 拥有者,因此必须降级为 dns.address_changed:
{
"age": 0,
"type": "network-error",
"url": "https://example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "192.0.2.3",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {},
"response_headers": {},
"status_code": 0,
"elapsed_time": 0,
"phase": "dns",
"type": "dns.address_changed"
}
}
用户代理再试图向 192.0.2.1 发送新请求,但依然无法建立连接。尽管用户代理曾经从 192.0.2.1 获得过 NEL 策略,但策略记录的“接收 IP 地址”仅保留最近一次获取时的(这里为
192.0.2.2),因此依然需要降级为 dns.address_changed:
{
"age": 0,
"type": "network-error",
"url": "https://example.com/",
"body": {
"sampling_fraction": 1.0,
"server_ip": "192.0.2.1",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {},
"response_headers": {},
"status_code": 0,
"elapsed_time": 0,
"phase": "dns",
"type": "dns.address_changed"
}
}
一个典型的应用需要几十个资源,这些资源通常通过 HTML、CSS 或 JavaScript 进行拉取。应用本身可以通过 onerror
回调等方式观察到部分失败,但无法获知导致失败的详细网络错误原因,例如 DNS 故障、TCP 错误、TLS 协议错误等。
为解决这一问题,应用可以为用于拉取子资源的第一方主机向用户代理注册相关的NEL 策略。这样,只要策略存在且遇到某一已注册origin资源的网络错误时,用户代理就会报告详细的网络错误,帮助开发者排查故障。
当资源被第三方嵌入时,资源提供者通常无法埋点或观察到失败。例如 example.com 在站点中嵌入了 widget.com/thing.js 资源,而访问
example.com 的用户如果因网络错误拉取该资源失败,widget.com 主机既不知晓也无法检测此失败。
为解决该问题,widget.com 可以为自身主机注册 NEL 策略。这样,只要策略生效,无论资源是从第一方还是第三方 origin 拉取,只要遇到网络错误——只要目标origin注册了NEL 策略,用户代理就会报告网络错误并使服务商能够排查问题。
NEL 提供的网络错误报告有可能暴露用户网络配置的新信息。例如攻击者可以滥用 NEL 上报来探测用户的网络结构,或者扫描用户内网服务器。此外,类似 HSTS、HPKP 和 CSP 钉扎策略,已存储的NEL 策略也可被用作“超级 Cookie”,通过定制唯一的(每用户)上报 URI 用于标识符,替代或协同 HTTP cookie 实现跟踪。
为降低上述风险,NEL 注册仅限于潜在可信源点,网络错误报告的投递同样只允许发往潜在可信源点。这样可防止短暂的 HTTP MITM 利用 NEL 作为持久追踪器。
此外,NEL 的 策略缓存按网络分区密钥进行分区,使得同一站点在不同嵌套场景下存储的NEL 策略不会被另一上下文复用(比如,被不同顶级站点嵌入时)。
NEL 旨在补充现有服务端监控功能。NEL 报告应只发给当前被请求服务的所有者。对于DNS 解析阶段发生的错误,只有当 NEL 策略由该错误域名命名树的所有者下发时,NEL 才会上报错误。对于发生在安全连接建立或 请求与响应传输阶段的错误,则只有 NEL 策略来自请求实际发往服务器的所有者时才会上报。
上述原因解释了 NEL 策略的接收 IP 地址和子域标志的处理方式。通过检查策略的接收 IP 是否与服务器IP一致,NEL 将策略的信任边界同时扩展到服务器,使其不仅仅信任策略origin,还要求校验实际通信服务器。这样可防止如 DNS 重绑定攻击(一方下发长期有效 NEL,随后变更 name server,把该 origin 指向另一个自己不控制服务器,导致用户代理把第二台服务器的报告发给攻击者)。
同样,子域相关的 NEL 策略也有限制,只允许在策略源点子域的DNS 解析阶段时上报。此时还未连接服务器,因此只需验证策略是由该 origin的超级域送达即可,允许域名所有者以 NEL 检测7.3 DNS 配置错误,防止恶意 DNS 收集不属于所有者的信息。
为防止信息泄露,NEL 关于某个 请求 的报告不会包含服务器在处理该请求时无法看到的任何信息。对DNS 解析阶段的错误,报告内容仅限于 DNS
层可获取信息。这可防止服务器滥用 NEL 收集更多用户信息。注意 NEL 报告会包含网站公网 IP(server_ip 字段),该 IP 未必总被服务端知晓(如位于负载均衡后)。
例如,NEL 报告不会包含任何关于具体使用了哪台 DNS 解析器解析请求domain name的信息。
除上述约束外,用户代理必须:
开发部署 NEL 时应当考虑 NEL 报告投递给指定收集器后的隐私影响。例如,报告可能包含带有敏感数据的 URL(如“能力型 URL”),需要特殊防护(见[CAPABILITY-URLS]), 并可能需要开发者自行部署 NEL 收集器以防止这类 URL 被第三方收到。
应按如下登记更新永久消息头字段注册表(见[RFC3864]):
NELNEL 响应头)request)
request)
response)
request)
report)
url)(片段)
url)(路径)
url)(查询)
本文件根据 [CSP] 和 [RFC6797] 规范的许可,复用了部分内容。此外,特别感谢 Julia Tuttle、Chris Bentzel、Todd Reifsteck、Aaron Heady 和 Mark Nottingham 对本工作所做出的宝贵评论与贡献。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: