CVE-2026-93379
Overview
Background
- ORB (Opaque Response Blocking)
- the network-service mechanism (successor to CORB) that decides whether a cross-origin
no-corsresponse may be delivered into a requesting renderer process, keeping sensitive cross-origin data out of processes that should not read it. - `opaque-blocklisted-never-sniffed` MIME types
- a list in
orb_mimetypes.ccof Content-Types that ORB always treats as protected and never subjects to content sniffing, because their contents are sensitive and sniffing cannot safely reclassify them. - `MimeType::kNeverSniffed`
- the classification an entry on that list maps to; a response so classified is blocked based on its declared
Content-Typeheader alone, with no fallback to sniffing the bytes. - `text/pdf`
- a non-standard but real-world Content-Type label for PDF documents, alongside the standard
application/pdfthat ORB already treated as never-sniffed.
Root Cause Analysis
Before the patch, the never-sniffed blocklist in orb_mimetypes.cc contained application/pdf but not the alternate text/pdf label, so a cross-origin PDF served with Content-Type: text/pdf was not classified as MimeType::kNeverSniffed. Because the label fell outside the protected set, ORB did not apply the header-based block that PDFs are supposed to receive, so such a response could be treated as sniffable and potentially allowed into a requesting renderer that had no cross-origin read authorization for it. The invariant violated is that ORB must protect PDF payloads regardless of which of the two commonly-used MIME labels the server used, since a PDF is sensitive document content either way.
The fix adds "text/pdf" to the same static list (and asserts the mapping in orb_mimetypes_unittest.cc), so the MIME classifier now returns kNeverSniffed for it and ORB blocks the response on the header alone. This is a TIGHTENING: the patch only adds an entry to the blocklist, widening the set of responses ORB refuses to hand to a renderer.
application/pdf label and omitted the equivalent text/pdf, leaving a labeling gap through which PDF content escaped authorization. Adding text/pdf to the never-sniffed list closes the gap so both labels are treated identically.Attack Path
- Attacker hosts a page A malicious site loads a resource whose real payload is a sensitive cross-origin PDF (for example one served only to an authenticated victim).
- Server labels it `text/pdf`
The target resource is delivered cross-origin with
Content-Type: text/pdfrather thanapplication/pdf, so it misses the pre-patch blocklist entry. - ORB fails to block
Because
text/pdfdid not map toMimeType::kNeverSniffed, ORB did not apply header-based blocking and the response was eligible to reach the attacker’s renderer instead of being withheld. (inferred: whether the response was ultimately delivered depends on ORB’s remaining sniffing path.) - Cross-origin data exposure The unauthorized PDF bytes become available in the attacker-controlled renderer process, defeating the cross-origin read protection ORB is meant to enforce. (inferred — the diff proves the classification gap, not a specific exfiltration primitive.)
Impact Assessment
text/pdf, into a renderer process that lacks authorization to read it, undermining ORB’s same-origin data confidentiality guarantee. The precondition is that the target server labels a sensitive PDF as text/pdf and that the resource is reachable via a no-cors cross-origin request; the impact is an incorrect-authorization / information-disclosure issue rather than memory corruption. The vendor advisory rates this high severity and does not report in-the-wild exploitation; NVD scores it CVSS 4.3. Any concrete cross-origin data leak beyond the classification gap is (inferred), and exploited-in-the-wild status and severity are not stated by the advisory.Files Changed
services/network/public/cpp/orb/orb_mimetypes_unittest.ccservices/network/public/cpp/orb/orb_mimetypes.cc
Audit Directions
- Alias and synonym gaps in security allow/block listsAudit every ORB/CORB/mime classification list for MIME types that have multiple real-world labels (e.g.
text/*vsapplication/*forms) and confirm all variants are enumerated, not just the canonical one. - Header-driven authorization decisionsReview code that gates cross-origin data delivery on an exact
Content-Typestring match, since any label a server can freely choose that is not covered lets protected content slip through. - Divergence between recognizers and blockersWhere one component recognizes a format (e.g.
text/pdfrecognized as a PDF per crbug.com/40774340) but a separate protection list must also list it, check that the two stay in sync so newly-recognized labels inherit the same protections.
Patch
From 0d54ca082631dcb2520240e6dcd4771464f74e77 Mon Sep 17 00:00:00 2001 From: Lukasz Anforowicz <[email protected]> Date: Fri, 11 Sep 2026 16:21:53 -0700 Subject: [PATCH] [orb] Add `text/pdf` to the `opaque-blocklisted-never-sniffed` list. ORB already protects `application/pdf` so this should be a reasonable change. It should have no web-visible change in behavior, except if images/video/etc are labeled as `text/pdf` (which seems unlikely in practice). This CL can be seen as a follow-up to https://crbug.com/40774340 which implemented support for recognizing `text/pdf` as a PDF document. https://github.com/annevk/orb/pull/46 corresponds to this change. Fixed: 560039872 Bug: 40774340 Change-Id: I09505eddfea8a85944cc3e6f7dcfd83f7efb5507 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8400027 Reviewed-by: Charlie Reis <[email protected]> Commit-Queue: Łukasz Anforowicz <[email protected]> Auto-Submit: Łukasz Anforowicz <[email protected]> Cr-Commit-Position: refs/heads/main@{#1696707} --- diff --git a/services/network/public/cpp/orb/orb_mimetypes.cc b/services/network/public/cpp/orb/orb_mimetypes.cc index 7be30d71..346f657 100644 --- a/services/network/public/cpp/orb/orb_mimetypes.cc +++ b/services/network/public/cpp/orb/orb_mimetypes.cc @@ -142,6 +142,7 @@ "application/vnd.spreadsheet-openxml", "application/vnd.wordprocessing-openxml", "text/csv", + "text/pdf", // Block signed documents to protect (potentially sensitive) unencrypted // body of the signed document. There should be no need to block // encrypted documents (e.g. `multipart/encrypted` nor diff --git a/services/network/public/cpp/orb/orb_mimetypes_unittest.cc b/services/network/public/cpp/orb/orb_mimetypes_unittest.cc index 6c65163..e40ea7e9 100644 --- a/services/network/public/cpp/orb/orb_mimetypes_unittest.cc +++ b/services/network/public/cpp/orb/orb_mimetypes_unittest.cc @@ -81,6 +81,7 @@ {"multipart/byteranges", MimeType::kNeverSniffed}, {"multipart/signed", MimeType::kNeverSniffed}, {"text/csv", MimeType::kNeverSniffed}, + {"text/pdf", MimeType::kNeverSniffed}, {"text/event-stream", MimeType::kNeverSniffed}, };
Regression Test / PoC
diff --git a/services/network/public/cpp/orb/orb_mimetypes_unittest.cc b/services/network/public/cpp/orb/orb_mimetypes_unittest.cc
index 6c65163..e40ea7e9 100644
--- a/services/network/public/cpp/orb/orb_mimetypes_unittest.cc
+++ b/services/network/public/cpp/orb/orb_mimetypes_unittest.cc
@@ -81,6 +81,7 @@
{"multipart/byteranges", MimeType::kNeverSniffed},
{"multipart/signed", MimeType::kNeverSniffed},
{"text/csv", MimeType::kNeverSniffed},
+ {"text/pdf", MimeType::kNeverSniffed},
{"text/event-stream", MimeType::kNeverSniffed},
};