
ma1 pushed to branch base-browser-128.13.0esr-14.5-1 at The Tor Project / Applications / Tor Browser Commits: 16d48c99 by Cathy Lu at 2025-07-22T01:59:35+02:00 Bug 1791322 - GeckoView should call classifyDownloads to sandbox downloads r=geckoview-reviewers,nika Differential Revision: https://phabricator.services.mozilla.com/D249683 - - - - - 2ac18296 by Tom Schuster at 2025-07-22T01:59:37+02:00 Bug 1808979 - WPT for frame-src path matching after replacing the URL. r=freddyb Differential Revision: https://phabricator.services.mozilla.com/D253638 - - - - - 6221ed58 by Tom Schuster at 2025-07-22T01:59:38+02:00 Bug 1808979 - Disable security.csp.truncate_blocked_uri_for_frame_navigations by default. r=freddyb Differential Revision: https://phabricator.services.mozilla.com/D253304 - - - - - 00cf1f42 by Andreas Pehrson at 2025-07-22T01:59:40+02:00 Bug 1971116 - For global mute events, iterate on copies of containers. r=dbaker Mute/unmute events are fired synchronously to content, which if it stops an (event target) track in the event handler, may call back into and mutate the containers we're iterating over. Differential Revision: https://phabricator.services.mozilla.com/D254352 - - - - - 7581b39d by Tom Schuster at 2025-07-22T01:59:41+02:00 Bug 1971704 - Cleanup nsContentSecurityUtils::ClassifyDownload. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D253491 - - - - - 15787e0c by Pier Angelo Vendrame at 2025-07-22T01:59:43+02:00 Bug 1972282 - Check for spoof English in xsl:sort. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D254784 - - - - - 9 changed files: - dom/media/MediaManager.cpp - dom/security/nsContentSecurityUtils.cpp - dom/security/nsContentSecurityUtils.h - dom/xslt/xpath/txXPathNode.h - dom/xslt/xslt/txNodeSorter.cpp - mobile/android/components/geckoview/GeckoViewStreamListener.cpp - modules/libpref/init/StaticPrefList.yaml - + testing/web-platform/tests/content-security-policy/frame-src/frame-src-blocked-path-matching.sub.html - uriloader/exthandler/nsExternalHelperAppService.cpp Changes: ===================================== dom/media/MediaManager.cpp ===================================== @@ -3513,7 +3513,9 @@ void MediaManager::OnCameraMute(bool aMute) { mCamerasMuted = aMute; // This is safe since we're on main-thread, and the windowlist can only // be added to from the main-thread - for (const auto& window : mActiveWindows.Values()) { + for (const auto& window : + ToTArray<AutoTArray<RefPtr<GetUserMediaWindowListener>, 2>>( + mActiveWindows.Values())) { window->MuteOrUnmuteCameras(aMute); } } @@ -3524,7 +3526,9 @@ void MediaManager::OnMicrophoneMute(bool aMute) { mMicrophonesMuted = aMute; // This is safe since we're on main-thread, and the windowlist can only // be added to from the main-thread - for (const auto& window : mActiveWindows.Values()) { + for (const auto& window : + ToTArray<AutoTArray<RefPtr<GetUserMediaWindowListener>, 2>>( + mActiveWindows.Values())) { window->MuteOrUnmuteMicrophones(aMute); } } @@ -4698,7 +4702,7 @@ void GetUserMediaWindowListener::MuteOrUnmuteCameras(bool aMute) { } mCamerasAreMuted = aMute; - for (auto& l : mActiveListeners) { + for (auto& l : mActiveListeners.Clone()) { if (l->GetDevice()->Kind() == MediaDeviceKind::Videoinput) { l->MuteOrUnmuteCamera(aMute); } @@ -4713,7 +4717,7 @@ void GetUserMediaWindowListener::MuteOrUnmuteMicrophones(bool aMute) { } mMicrophonesAreMuted = aMute; - for (auto& l : mActiveListeners) { + for (auto& l : mActiveListeners.Clone()) { if (l->GetDevice()->Kind() == MediaDeviceKind::Audioinput) { l->MuteOrUnmuteMicrophone(aMute); } ===================================== dom/security/nsContentSecurityUtils.cpp ===================================== @@ -1663,11 +1663,17 @@ void nsContentSecurityUtils::LogMessageToConsole(nsIHttpChannel* aChannel, } /* static */ -long nsContentSecurityUtils::ClassifyDownload( - nsIChannel* aChannel, const nsAutoCString& aMimeTypeGuess) { +long nsContentSecurityUtils::ClassifyDownload(nsIChannel* aChannel) { MOZ_ASSERT(aChannel, "IsDownloadAllowed without channel?"); nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); + if ((loadInfo->GetTriggeringSandboxFlags() & SANDBOXED_ALLOW_DOWNLOADS) || + (loadInfo->GetSandboxFlags() & SANDBOXED_ALLOW_DOWNLOADS)) { + if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) { + LogMessageToConsole(httpChannel, "IframeSandboxBlockedDownload"); + } + return nsITransfer::DOWNLOAD_FORBIDDEN; + } nsCOMPtr<nsIURI> contentLocation; aChannel->GetURI(getter_AddRefs(contentLocation)); @@ -1698,27 +1704,11 @@ long nsContentSecurityUtils::ClassifyDownload( if (StaticPrefs::dom_block_download_insecure() && decission != nsIContentPolicy::ACCEPT) { - nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel); - if (httpChannel) { + if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) { LogMessageToConsole(httpChannel, "MixedContentBlockedDownload"); } return nsITransfer::DOWNLOAD_POTENTIALLY_UNSAFE; } - if (loadInfo->TriggeringPrincipal()->IsSystemPrincipal()) { - return nsITransfer::DOWNLOAD_ACCEPTABLE; - } - - uint32_t triggeringFlags = loadInfo->GetTriggeringSandboxFlags(); - uint32_t currentflags = loadInfo->GetSandboxFlags(); - - if ((triggeringFlags & SANDBOXED_ALLOW_DOWNLOADS) || - (currentflags & SANDBOXED_ALLOW_DOWNLOADS)) { - nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel); - if (httpChannel) { - LogMessageToConsole(httpChannel, "IframeSandboxBlockedDownload"); - } - return nsITransfer::DOWNLOAD_FORBIDDEN; - } return nsITransfer::DOWNLOAD_ACCEPTABLE; } ===================================== dom/security/nsContentSecurityUtils.h ===================================== @@ -75,8 +75,7 @@ class nsContentSecurityUtils { const mozilla::dom::Element& aElement); // Helper function to Check if a Download is allowed; - static long ClassifyDownload(nsIChannel* aChannel, - const nsAutoCString& aMimeTypeGuess); + static long ClassifyDownload(nsIChannel* aChannel); // Public only for testing static FilenameTypeAndDetails FilenameToFilenameType( ===================================== dom/xslt/xpath/txXPathNode.h ===================================== @@ -66,6 +66,8 @@ class txXPathNode { bool operator!=(const txXPathNode& aNode) const { return !(*this == aNode); } ~txXPathNode() { MOZ_COUNT_DTOR(txXPathNode); } + mozilla::dom::Document* OwnerDoc() const { return mNode->OwnerDoc(); } + private: friend class txXPathNativeNode; friend class txXPathNodeUtils; ===================================== dom/xslt/xslt/txNodeSorter.cpp ===================================== @@ -13,10 +13,13 @@ #include "mozilla/CheckedInt.h" #include "mozilla/UniquePtrExtensions.h" +#include "nsRFPService.h" using mozilla::CheckedUint32; using mozilla::MakeUnique; using mozilla::MakeUniqueFallible; +using mozilla::nsRFPService; +using mozilla::RFPTarget; using mozilla::UniquePtr; /* @@ -74,6 +77,10 @@ nsresult txNodeSorter::addSortElement(Expr* aSelectExpr, Expr* aLangExpr, if (aLangExpr) { rv = aLangExpr->evaluateToString(aContext, lang); NS_ENSURE_SUCCESS(rv, rv); + } else if (aContext->getContextNode() + .OwnerDoc() + ->ShouldResistFingerprinting(RFPTarget::JSLocale)) { + CopyUTF8toUTF16(nsRFPService::GetSpoofedJSLocale(), lang); } // Case-order ===================================== mobile/android/components/geckoview/GeckoViewStreamListener.cpp ===================================== @@ -16,6 +16,8 @@ #include "nsIWebProgressListener.h" #include "nsIX509Cert.h" #include "nsPrintfCString.h" +#include "nsContentSecurityUtils.h" +#include "nsITransfer.h" #include "nsNetUtil.h" @@ -85,6 +87,16 @@ GeckoViewStreamListener::OnStartRequest(nsIRequest* aRequest) { return NS_OK; } + nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); + if (channel) { + int32_t classification = nsContentSecurityUtils::ClassifyDownload(channel); + if (classification == nsITransfer::DOWNLOAD_FORBIDDEN) { + channel->Cancel(NS_ERROR_ABORT); + CompleteWithError(NS_ERROR_ABORT, channel); + return NS_OK; + } + } + // We're expecting data later via OnDataAvailable, so create the stream now. InitializeStreamSupport(aRequest); ===================================== modules/libpref/init/StaticPrefList.yaml ===================================== @@ -14658,7 +14658,7 @@ - name: security.csp.truncate_blocked_uri_for_frame_navigations type: bool - value: true + value: false mirror: always # Limit the number of CSP reports that are send in a specific timespan. ===================================== testing/web-platform/tests/content-security-policy/frame-src/frame-src-blocked-path-matching.sub.html ===================================== @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<head> + <!-- Make sure frame-src does path matching --> + <meta http-equiv="Content-Security-Policy" content="frame-src data: https://{{hosts[][www1]}}:{{ports[https][0]}}/content-security-policy/support/;"> + <title>frame-src-blocked-path-matching</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <script> + async_test(t => { + let frame = document.createElement("iframe"); + frame.src = "https://{{hosts[][www1]}}:{{ports[https][0]}}/content-security-policy/support/postmessage-pass.html"; + + window.addEventListener('message', t.step_func(e => { + if (e.source === frame.contentWindow) { + assert_equals(e.data, "PASS"); + t.done(); + } + })); + + document.body.append(frame); + }, "Cross-origin frame with allowed path loads"); + + async_test(t => { + let frame = document.createElement("iframe"); + frame.src = "https://{{hosts[][www1]}}:{{ports[https][0]}}/content-security-policy/resource/"; + + window.addEventListener('securitypolicyviolation', t.step_func_done(e => { + assert_equals(e.blockedURI, "https://{{hosts[][www1]}}:{{ports[https][0]}}"); + assert_equals(e.effectiveDirective, "frame-src"); + }), { once: true }); + + document.body.append(frame); + }, "Cross-origin frame with other path is blocked"); + + async_test(t => { + let frame = document.createElement("iframe"); + frame.src = "data:text/html,<h1>Hello World</h1>" + frame.onload = t.step_func(() => { + frame.src = "https://{{hosts[][www1]}}:{{ports[https][0]}}/content-security-policy/resource/"; + + window.addEventListener('securitypolicyviolation', t.step_func_done(e => { + assert_equals(e.blockedURI, "https://{{hosts[][www1]}}:{{ports[https][0]}}"); + assert_equals(e.effectiveDirective, "frame-src"); + }), { once: true }); + }); + document.body.append(frame); + }, "Cross-origin frame with other path is blocked even after replacing the already loaded URL"); + </script> + </body> +</html> ===================================== uriloader/exthandler/nsExternalHelperAppService.cpp ===================================== @@ -1584,8 +1584,7 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) { return NS_OK; } - mDownloadClassification = - nsContentSecurityUtils::ClassifyDownload(aChannel, MIMEType); + mDownloadClassification = nsContentSecurityUtils::ClassifyDownload(aChannel); if (mDownloadClassification == nsITransfer::DOWNLOAD_FORBIDDEN) { // If the download is rated as forbidden, View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/a6492cd... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/a6492cd... You're receiving this email because of your account on gitlab.torproject.org.
participants (1)
-
ma1 (@ma1)