Firefox · Toolkit
CVE-2026-0887
Logic Error in Toolkit
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
add_tasktoolkit/components/pdfjs/test/browser_pdfjs_response_link.js |
modified |
Files Changed
toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjstoolkit/components/pdfjs/test/browser.tomltoolkit/components/pdfjs/test/browser_pdfjs_response_link.jstoolkit/components/pdfjs/test/pdf_response_link.sjs
Patch
diff --git a/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs b/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs
index 7a05366416c..fb4d0fe8949 100644
--- a/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs
+++ b/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs
@@ -1213,6 +1213,9 @@ PdfStreamConverter.prototype = {
);
// The viewer does not need to handle HTTP Refresh header.
aRequest.setResponseHeader("Refresh", "", false);
+ // There is no reason to load something via <link>: the only external
+ // resource is the pdf itself.
+ aRequest.setResponseHeader("Link", "", false);
}
lazy.PdfJsTelemetryContent.onViewerIsUsed();
diff --git a/toolkit/components/pdfjs/test/browser.toml b/toolkit/components/pdfjs/test/browser.toml
index 50ec75f988b..e1f80550fa8 100644
--- a/toolkit/components/pdfjs/test/browser.toml
+++ b/toolkit/components/pdfjs/test/browser.toml
@@ -102,6 +102,9 @@ support-files = [
["browser_pdfjs_properties.js"]
+["browser_pdfjs_response_link.js"]
+support-files = ["pdf_response_link.sjs"]
+
["browser_pdfjs_saveas.js"]
support-files = [
"!/toolkit/content/tests/browser/common/mockTransfer.js",
diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_response_link.js b/toolkit/components/pdfjs/test/browser_pdfjs_response_link.js
new file mode 100644
index 00000000000..9b8833801d1
--- /dev/null
+++ b/toolkit/components/pdfjs/test/browser_pdfjs_response_link.js
@@ -0,0 +1,46 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const RELATIVE_DIR = "toolkit/components/pdfjs/test/";
+const TESTROOT = "https://example.com/browser/" + RELATIVE_DIR;
+
+function getBodyBackgroundColor(browser) {
+ return SpecialPowers.spawn(browser, [], async () => {
+ return content.getComputedStyle(content.document.querySelector("body"))
+ .backgroundColor;
+ });
+}
+
+// Sanity check: the pdf test does not trivially pass due to the lack of support
+// for Link header.
+add_task(async function test_plain_text_with_link_in_response() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: `${TESTROOT}pdf_response_link.sjs?text` },
+ async function (browser) {
+ const bodyBackgroundColor = await getBodyBackgroundColor(browser);
+ Assert.equal(
+ bodyBackgroundColor,
+ "rgb(255, 0, 0)",
+ "Body background is red"
+ );
+ }
+ );
+});
+
+add_task(async function test_pdf_with_link_in_response() {
+ makePDFJSHandler();
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: "about:blank" },
+ async function (browser) {
+ await waitForPdfJSCanvas(browser, `${TESTROOT}pdf_response_link.sjs?pdf`);
+ const bodyBackgroundColor = await getBodyBackgroundColor(browser);
+ Assert.notEqual(
+ bodyBackgroundColor,
+ "rgb(255, 0, 0)",
+ "Body background is not red"
+ );
+ await waitForPdfJSClose(browser);
+ }
+ );
+});
diff --git a/toolkit/components/pdfjs/test/pdf_response_link.sjs b/toolkit/components/pdfjs/test/pdf_response_link.sjs
new file mode 100644
index 00000000000..fd5d3aff44f
--- /dev/null
+++ b/toolkit/components/pdfjs/test/pdf_response_link.sjs
@@ -0,0 +1,24 @@
+const DATA = {
+ pdf: {
+ mimetype: "application/pdf",
+ content:
+ "%PDF-1.\ntrailer<</Root<</Pages<</Kids[<</MediaBox[0 0 3 3]>>]>>>>>>",
+ },
+ text: {
+ mimetype: "text/plain",
+ content: "hello world",
+ },
+};
+
+function handleRequest(request, response) {
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader(
+ "Link",
+ "<data:text/css,body{background:red%20!important;}>; rel=stylesheet",
+ false
+ );
+ response.setStatusLine(request.httpVersion, "200", "Found");
+ const { mimetype, content } = DATA[request.queryString];
+ response.setHeader("Content-Type", mimetype, false);
+ response.write(content);
+}
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/toolkit/components/pdfjs/test/browser.toml b/toolkit/components/pdfjs/test/browser.toml
index 50ec75f988b..e1f80550fa8 100644
--- a/toolkit/components/pdfjs/test/browser.toml
+++ b/toolkit/components/pdfjs/test/browser.toml
@@ -102,6 +102,9 @@ support-files = [
["browser_pdfjs_properties.js"]
+["browser_pdfjs_response_link.js"]
+support-files = ["pdf_response_link.sjs"]
+
["browser_pdfjs_saveas.js"]
support-files = [
"!/toolkit/content/tests/browser/common/mockTransfer.js",
diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_response_link.js b/toolkit/components/pdfjs/test/browser_pdfjs_response_link.js
new file mode 100644
index 00000000000..9b8833801d1
--- /dev/null
+++ b/toolkit/components/pdfjs/test/browser_pdfjs_response_link.js
@@ -0,0 +1,46 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const RELATIVE_DIR = "toolkit/components/pdfjs/test/";
+const TESTROOT = "https://example.com/browser/" + RELATIVE_DIR;
+
+function getBodyBackgroundColor(browser) {
+ return SpecialPowers.spawn(browser, [], async () => {
+ return content.getComputedStyle(content.document.querySelector("body"))
+ .backgroundColor;
+ });
+}
+
+// Sanity check: the pdf test does not trivially pass due to the lack of support
+// for Link header.
+add_task(async function test_plain_text_with_link_in_response() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: `${TESTROOT}pdf_response_link.sjs?text` },
+ async function (browser) {
+ const bodyBackgroundColor = await getBodyBackgroundColor(browser);
+ Assert.equal(
+ bodyBackgroundColor,
+ "rgb(255, 0, 0)",
+ "Body background is red"
+ );
+ }
+ );
+});
+
+add_task(async function test_pdf_with_link_in_response() {
+ makePDFJSHandler();
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: "about:blank" },
+ async function (browser) {
+ await waitForPdfJSCanvas(browser, `${TESTROOT}pdf_response_link.sjs?pdf`);
+ const bodyBackgroundColor = await getBodyBackgroundColor(browser);
+ Assert.notEqual(
+ bodyBackgroundColor,
+ "rgb(255, 0, 0)",
+ "Body background is not red"
+ );
+ await waitForPdfJSClose(browser);
+ }
+ );
+});
diff --git a/toolkit/components/pdfjs/test/pdf_response_link.sjs b/toolkit/components/pdfjs/test/pdf_response_link.sjs
new file mode 100644
index 00000000000..fd5d3aff44f
--- /dev/null
+++ b/toolkit/components/pdfjs/test/pdf_response_link.sjs
@@ -0,0 +1,24 @@
+const DATA = {
+ pdf: {
+ mimetype: "application/pdf",
+ content:
+ "%PDF-1.\ntrailer<</Root<</Pages<</Kids[<</MediaBox[0 0 3 3]>>]>>>>>>",
+ },
+ text: {
+ mimetype: "text/plain",
+ content: "hello world",
+ },
+};
+
+function handleRequest(request, response) {
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader(
+ "Link",
+ "<data:text/css,body{background:red%20!important;}>; rel=stylesheet",
+ false
+ );
+ response.setStatusLine(request.httpVersion, "200", "Found");
+ const { mimetype, content } = DATA[request.queryString];
+ response.setHeader("Content-Type", mimetype, false);
+ response.write(content);
+}
Loading diff…
References
On This Page