Description
I want to extend Network Error Logging to support Signed Exchange.
Signed Exchange feature enables content publishers to sign their contents using their own private keys. User Agents (UAs) can trust the signed contents as if the contents are served from the publisher’s origins even if they are served from other distributors’ origins. Even if there is no network errors, UA may fail to load the signed content (example: the signature of the content has expired). This case is not covered by the Network Error Logging feature now. Both publishers and distributors can’t recognize the errors in the user’s environment. I want to extend Network Error Logging feature to enable both publishers and distributors to investigate the signed exchange loading errors such as certificate verification errors.
Distributor side reporting
A publisher (publisher.example) signed the article (https://publisher.example/article.html) as article.html.sxg. A distributor (distributor.example) is distributing the content at https://distributor.example/publisher.example/article.html.sxg and the certificate of publisher.example at https://distributor.example/publisher.example/cert.
If the distributor wants to investigate the signed exchange logs, the distributor sets the Report-To and NEL header in the HTTP response. This is same as the existing Network Error Logging feature.
Report-To: {"group": "sxg-errors",
"max_age": 10886400,
"endpoints": [{ "url": "https://report.distributor.example/" }] }
NEL: {"report_to": "sxg-errors", "max_age": 2592000}
Once UA receives the Report-To and NEL header, when UA failed to load (prefetch or navigation) the signed exchange content in the origin (https://distributor.example) because the signature has expired, UA should send the report to the end point https://report.distributor.example/.
{
"type": "signed-exchange",
"age": 1,
"url": "https://distributor.example/publisher.example/article.html.sxg",
"user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) ...",
"body": {
"type": "failed",
"outer_url": "https://distributor.example/publisher.example/article.html.sxg",
"inner_url": "https://publisher.example/article.html",
"cert_url": "https://distributor.example/publisher.example/cert",
"sampling_fraction": 1
}
}
Publisher side reporting
If the publisher wants to investigate the signed exchange logs, the publisher sets the Report-To and NEL in the signed response header of the signed exchange.
Report-To: {"group": "sxg-errors",
"max_age": 10886400,
"endpoints": [{ "url": "https://report.publisher.example/" }] }
NEL: {"report_to": "sxg-errors", "max_age": 2592000}
Same as distributor side reporting, UA should send the report to the end point https://report.publisher.example/ when the UA failed to navigate to the signed exchange content.
{
"type": "signed-exchange",
"age": 1,
"url": "https://publisher.example/article.html",
"user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) ...",
"body": {
"type": "failed",
"outer_url": "https://distributor.example/publisher.example/article.html.sxg",
"inner_url": "https://publisher.example/article.html",
"cert_url": "https://distributor.example/publisher.example/cert",
"sampling_fraction": 1
}
}
UAs must not send the report to the publisher when the UA loaded the signed exchange for prefetching, because prefetching signed exchange must be done in a privacy-preserving manner.
Error types
UA will expose the following error types.
- ok
"ok" is sent only when success_fraction of NEL header is set larger than 0.0. - failed
The following detailed error types should be used only when the reporting origin (the distributor or the publisher) is same as the origin of cert-url of the signed exchange. See Hiding detailed error type section.
- non_secure_origin
- parse_error
- unsupported_version
- network_error
- cert_fetch_error
- cert_parse_error
- signature_verification_error
- cert_verification_error
- ct_verification_error
- ocsp_error
- cert_requirements_not_met
- mi_error
Hiding detailed error type
If the reporting origin (the distributor or the publisher) is different from the origin of cert url, UA must send only ok or failed. This is intended to avoid the leaking of cross-origin information in cert_url.
For example an evil attacker can do the port-scanning by checking whether the error type is cert_fetch_error or cert_parse_error if UA sends the detailed error types. Example:
- An attacker of https://evil.example/ signs attack.html as attack.html.sxg.
- A target user opens https://evil.example/attack.html.sxg.
- The evil.example returns the sxg whose cert_url is https://127-0-0-1.evil.example:8080/ and with Report-to (https://evil.example/report) header.
- The attacker set the DNS of 127-0-0-1.evil.example point to 127.0.0.1.
- If evil.example/report receives cert_parse_error error, the attacker can know that the target user is running a HTTP server.