Firefox · ImageLib
CVE-2026-16354
Logic Error in ImageLib
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifimage/imgRequest.cpp |
modified | |
GetHadCrossOriginRedirectsimage/imgRequestProxy.cpp |
modified | |
ifimage/imgRequestProxy.cpp |
modified |
Files Changed
image/imgRequest.cppimage/imgRequest.himage/imgRequestProxy.cpptesting/web-platform/meta/fetch/images/canvas-remote-read-remote-image-redirect.html.ini
Patch
diff --git a/image/imgRequest.cpp b/image/imgRequest.cpp
index a7f7a8d8036..5b3676a9afa 100644
--- a/image/imgRequest.cpp
+++ b/image/imgRequest.cpp
@@ -622,6 +622,22 @@ bool imgRequest::HadInsecureRedirect() const {
return mHadInsecureRedirect;
}
+bool imgRequest::HadCrossOriginRedirects() const {
+ // While the channel is still around (during the load) read the authoritative
+ // value from it; afterwards fall back to the value latched in OnStopRequest.
+ // Ignore internal redirects (e.g. a service worker substituting a same-origin
+ // response for a cross-origin request): those are not cross-origin data flow
+ // and must not taint. Real cross-origin redirects (incl. bounce-backs) count.
+ if (mTimedChannel) {
+ bool allRedirectsSameOrigin = false;
+ return NS_SUCCEEDED(
+ mTimedChannel->GetAllRedirectsSameOriginIgnoringInternal(
+ &allRedirectsSameOrigin)) &&
+ !allRedirectsSameOrigin;
+ }
+ return mHadCrossOriginRedirects;
+}
+
/** nsIRequestObserver methods **/
NS_IMETHODIMP
@@ -817,6 +833,18 @@ imgRequest::OnStopRequest(nsIRequest* aRequest, nsresult status) {
progressTracker->SyncNotifyProgress(progress);
}
+ // Store whether the load involved a cross-origin redirect before we drop the
+ // timed channel. Internal redirects (e.g. a service worker serving a
+ // same-origin response for a cross-origin request) are ignored so we don't
+ // over-taint; real cross-origin redirects (incl. bounce-backs) still count.
+ if (mTimedChannel) {
+ bool allRedirectsSameOrigin = false;
+ mHadCrossOriginRedirects =
+ NS_SUCCEEDED(mTimedChannel->GetAllRedirectsSameOriginIgnoringInternal(
+ &allRedirectsSameOrigin)) &&
+ !allRedirectsSameOrigin;
+ }
+
mTimedChannel = nullptr;
return NS_OK;
}
diff --git a/image/imgRequest.h b/image/imgRequest.h
index 33497c94782..febd6d65529 100644
--- a/image/imgRequest.h
+++ b/image/imgRequest.h
@@ -165,6 +165,10 @@ class imgRequest final : public nsIThreadRetargetableStreamListener,
nsITimedChannel* GetTimedChannel() const { return mTimedChannel; }
+ /// Returns true if any redirect in the chain that loaded this image was
+ /// cross-origin.
+ bool HadCrossOriginRedirects() const;
+
imgCacheValidator* GetValidator() const { return mValidator; }
void SetValidator(imgCacheValidator* aValidator) { mValidator = aValidator; }
@@ -285,6 +289,8 @@ class imgRequest final : public nsIThreadRetargetableStreamListener,
bool mIsCrossSiteNoCORSRequest;
bool mShouldReportRenderTimeForLCP;
+ // True if any redirect in the chain that loaded this image was cross-origin.
+ bool mHadCrossOriginRedirects = false;
// SVGs can't be OffMainThread for example
bool mOffMainThreadData = false;
diff --git a/image/imgRequestProxy.cpp b/image/imgRequestProxy.cpp
index 1067f9ba827..9a41d868e02 100644
--- a/image/imgRequestProxy.cpp
+++ b/image/imgRequestProxy.cpp
@@ -873,17 +873,8 @@ imgRequestProxy::GetImagePrincipal(nsIPrincipal** aPrincipal) {
NS_IMETHODIMP
imgRequestProxy::GetHadCrossOriginRedirects(bool* aHadCrossOriginRedirects) {
- *aHadCrossOriginRedirects = false;
-
- nsCOMPtr<nsITimedChannel> timedChannel = TimedChannel();
- if (timedChannel) {
- bool allRedirectsSameOrigin = false;
- *aHadCrossOriginRedirects =
- NS_SUCCEEDED(timedChannel->GetAllRedirectsSameOriginIgnoringInternal(
- &allRedirectsSameOrigin)) &&
- !allRedirectsSameOrigin;
- }
-
+ *aHadCrossOriginRedirects =
+ GetOwner() ? GetOwner()->HadCrossOriginRedirects() : false;
return NS_OK;
}
diff --git a/testing/web-platform/meta/fetch/images/canvas-remote-read-remote-image-redirect.html.ini b/testing/web-platform/meta/fetch/images/canvas-remote-read-remote-image-redirect.html.ini
deleted file mode 100644
index 33630ce7eba..00000000000
--- a/testing/web-platform/meta/fetch/images/canvas-remote-read-remote-image-redirect.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[canvas-remote-read-remote-image-redirect.html]
- [Load a no-cors image from a same-origin URL that redirects to a cross-origin URL that redirects to the initial origin]
- expected: FAIL
-
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/testing/web-platform/meta/fetch/images/canvas-remote-read-remote-image-redirect.html.ini b/testing/web-platform/meta/fetch/images/canvas-remote-read-remote-image-redirect.html.ini deleted file mode 100644 index 33630ce7eba..00000000000 --- a/testing/web-platform/meta/fetch/images/canvas-remote-read-remote-image-redirect.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[canvas-remote-read-remote-image-redirect.html] - [Load a no-cors image from a same-origin URL that redirects to a cross-origin URL that redirects to the initial origin] - expected: FAIL -
Loading diff…
References
On This Page