lists.torproject.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

tbb-commits

Thread Start a new thread
Threads by month
  • ----- 2025 -----
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2015 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2014 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
tbb-commits@lists.torproject.org

August 2025

  • 1 participants
  • 197 discussions
[Git][tpo/applications/tor-browser] Pushed new tag base-browser-128.14.0esr-14.5-1-build2
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed new tag base-browser-128.14.0esr-14.5-1-build2 at The Tor Project / Applications / Tor Browser -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/base-brow… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][base-browser-128.14.0esr-14.5-1] 4 commits: Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed to branch base-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser Commits: eab03ce4 by Tom Schuster at 2025-08-18T13:27:42+02:00 Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao Differential Revision: https://phabricator.services.mozilla.com/D256648 BB 44100: cherry-picked except tests - - - - - b931045e by Tom Schuster at 2025-08-18T13:27:44+02:00 Bug 1701974 - Use x-kde-passwordManagerHint when copying private data to the clipboard. r=stransky Differential Revision: https://phabricator.services.mozilla.com/D256781 - - - - - 4284035c by Tom Schuster at 2025-08-18T13:27:45+02:00 Bug 1973900 - Remove support for the codebase attribute from <object>. r=farre,dom-core Differential Revision: https://phabricator.services.mozilla.com/D254958 - - - - - 24863cbf by Kershaw Chang at 2025-08-18T13:27:47+02:00 Bug 1979955 - ensure transaction is alive (for ESR140), a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D260484 - - - - - 7 changed files: - browser/actors/ClickHandlerChild.sys.mjs - browser/app/profile/firefox.js - dom/base/nsObjectLoadingContent.cpp - modules/libpref/init/StaticPrefList.yaml - netwerk/protocol/http/nsHttpConnection.cpp - testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html - widget/gtk/nsClipboard.cpp Changes: ===================================== browser/actors/ClickHandlerChild.sys.mjs ===================================== @@ -12,12 +12,26 @@ ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs", }); +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "autoscrollEnabled", + "general.autoScroll", + true +); + +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "blockJavascript", + "browser.link.alternative_click.block_javascript", + true +); + export class MiddleMousePasteHandlerChild extends JSWindowActorChild { handleEvent(clickEvent) { if ( clickEvent.defaultPrevented || clickEvent.button != 1 || - MiddleMousePasteHandlerChild.autoscrollEnabled + lazy.autoscrollEnabled ) { return; } @@ -34,13 +48,6 @@ export class MiddleMousePasteHandlerChild extends JSWindowActorChild { } } -XPCOMUtils.defineLazyPreferenceGetter( - MiddleMousePasteHandlerChild, - "autoscrollEnabled", - "general.autoScroll", - true -); - export class ClickHandlerChild extends JSWindowActorChild { handleEvent(wrapperEvent) { this.handleClickEvent(wrapperEvent.sourceEvent); @@ -112,6 +119,14 @@ export class ClickHandlerChild extends JSWindowActorChild { }; if (href && !isFromMiddleMousePasteHandler) { + if ( + lazy.blockJavascript && + Services.io.extractScheme(href) == "javascript" + ) { + // We don't want to open new tabs or windows for javascript: links. + return; + } + try { Services.scriptSecurityManager.checkLoadURIStrWithPrincipal( principal, ===================================== browser/app/profile/firefox.js ===================================== @@ -880,6 +880,9 @@ pref("browser.link.open_newwindow.restriction", 2); pref("browser.link.open_newwindow.disabled_in_fullscreen", false); #endif +// If true, opening javscript: URLs using middle-click, CTRL+click etc. are blocked. +pref("browser.link.alternative_click.block_javascript", true); + // Tabbed browser pref("browser.tabs.closeTabByDblclick", false); pref("browser.tabs.closeWindowWithLastTab", true); ===================================== dom/base/nsObjectLoadingContent.cpp ===================================== @@ -73,6 +73,7 @@ #include "mozilla/PresShell.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/StaticPrefs_browser.h" +#include "mozilla/StaticPrefs_dom.h" #include "nsChannelClassifier.h" #include "nsFocusManager.h" #include "ReferrerInfo.h" @@ -720,11 +721,12 @@ nsObjectLoadingContent::UpdateObjectParameters() { /// Codebase /// - nsAutoString codebaseStr; nsIURI* docBaseURI = el->GetBaseURI(); - el->GetAttr(nsGkAtoms::codebase, codebaseStr); - if (!codebaseStr.IsEmpty()) { + nsAutoString codebaseStr; + el->GetAttr(nsGkAtoms::codebase, codebaseStr); + if (StaticPrefs::dom_object_embed_codebase_enabled() && + !codebaseStr.IsEmpty()) { rv = nsContentUtils::NewURIWithDocumentCharset( getter_AddRefs(newBaseURI), codebaseStr, el->OwnerDoc(), docBaseURI); if (NS_FAILED(rv)) { ===================================== modules/libpref/init/StaticPrefList.yaml ===================================== @@ -3206,6 +3206,12 @@ value: true mirror: always +# Whether the codebase attribute in an <object> is used as the base URI. +- name: dom.object_embed.codebase.enabled + type: bool + value: false + mirror: always + # Whether origin trials are enabled. - name: dom.origin-trials.enabled type: bool ===================================== netwerk/protocol/http/nsHttpConnection.cpp ===================================== @@ -1663,9 +1663,10 @@ nsresult nsHttpConnection::OnSocketWritable() { } LOG((" writing transaction request stream\n")); - rv = mTransaction->ReadSegmentsAgain(this, - nsIOService::gDefaultSegmentSize, - &transactionBytes, &again); + RefPtr<nsAHttpTransaction> transaction = mTransaction; + rv = transaction->ReadSegmentsAgain(this, + nsIOService::gDefaultSegmentSize, + &transactionBytes, &again); if (mTlsHandshaker->EarlyDataUsed()) { mContentBytesWritten0RTT += transactionBytes; if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) { @@ -1688,7 +1689,8 @@ nsresult nsHttpConnection::OnSocketWritable() { static_cast<uint32_t>(mSocketOutCondition), again)); // XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF. - if (rv == NS_BASE_STREAM_CLOSED && !mTransaction->IsDone()) { + if (rv == NS_BASE_STREAM_CLOSED && + (mTransaction && !mTransaction->IsDone())) { rv = NS_OK; transactionBytes = 0; } @@ -1731,7 +1733,8 @@ nsresult nsHttpConnection::OnSocketWritable() { // When Spdy tunnel is used we need to explicitly set when a request is // done. if ((mState != HttpConnectionState::SETTING_UP_TUNNEL) && !mSpdySession) { - nsHttpTransaction* trans = mTransaction->QueryHttpTransaction(); + nsHttpTransaction* trans = + mTransaction ? mTransaction->QueryHttpTransaction() : nullptr; // needed for websocket over h2 (direct) if (!trans || !trans->IsWebsocketUpgrade()) { mRequestDone = true; @@ -1835,7 +1838,8 @@ nsresult nsHttpConnection::OnSocketReadable() { rv = NS_ERROR_FAILURE; LOG((" No Transaction In OnSocketWritable\n")); } else { - rv = mTransaction->WriteSegmentsAgain( + RefPtr<nsAHttpTransaction> transaction = mTransaction; + rv = transaction->WriteSegmentsAgain( this, nsIOService::gDefaultSegmentSize, &n, &again); } LOG(("nsHttpConnection::OnSocketReadable %p trans->ws rv=%" PRIx32 ===================================== testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html ===================================== @@ -30,4 +30,17 @@ async_test(t => { obj.onerror = t.unreached_func(); document.body.appendChild(obj); }, "object's typemustmatch content attribute should not be supported"); + +async_test(t => { + const obj = document.createElement("object"); + t.add_cleanup(() => obj.remove()); + obj.setAttribute("data", "/common/blank.html"); + obj.setAttribute("codebase", "https://test.invalid/"); + obj.onload = t.step_func_done(() => { + assert_not_equals(obj.contentDocument, null, "/common/blank.html should be loaded"); + assert_equals(obj.contentDocument.location.origin, location.origin, "document should be loaded with current origin as base"); + }); + obj.onerror = t.unreached_func(); + document.body.appendChild(obj); +}, "object's codebase content attribute should not be supported"); </script> ===================================== widget/gtk/nsClipboard.cpp ===================================== @@ -66,6 +66,10 @@ static const char kHTMLMarkupPrefix[] = static const char kURIListMime[] = "text/uri-list"; +// MIME to exclude sensitive data (password) from the clipboard history on not +// just KDE. +static const char kKDEPasswordManagerHintMime[] = "x-kde-passwordManagerHint"; + ClipboardTargets nsRetrievalContext::sClipboardTargets; ClipboardTargets nsRetrievalContext::sPrimaryTargets; @@ -323,6 +327,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, gtk_target_list_add(list, atom, 0, 0); } + // Try to exclude private data from clipboard history. + if (aTransferable->GetIsPrivateData()) { + GdkAtom atom = gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE); + gtk_target_list_add(list, atom, 0, 0); + } + // Get GTK clipboard (CLIPBOARD or PRIMARY) GtkClipboard* gtkClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); @@ -1313,6 +1323,22 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, return; } + if (selectionTarget == gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE)) { + if (!trans->GetIsPrivateData()) { + MOZ_CLIPBOARD_LOG( + " requested %s, but the data isn't actually private!\n", + kKDEPasswordManagerHintMime); + return; + } + + static const char* kSecret = "secret"; + MOZ_CLIPBOARD_LOG(" Setting data to '%s' for %s\n", kSecret, + kKDEPasswordManagerHintMime); + gtk_selection_data_set(aSelectionData, selectionTarget, 8, + (const guchar*)kSecret, strlen(kSecret)); + return; + } + MOZ_CLIPBOARD_LOG(" Try if we have anything at GetTransferData() for %s\n", GUniquePtr<gchar>(gdk_atom_name(selectionTarget)).get()); View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/a8cacb… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/a8cacb… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/mullvad-browser] Pushed new tag mullvad-browser-128.14.0esr-14.5-1-build2
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed new tag mullvad-browser-128.14.0esr-14.5-1-build2 at The Tor Project / Applications / Mullvad Browser -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/tree/mullv… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/mullvad-browser] Pushed new tag mullvad-browser-140.2.0esr-15.0-1-build2
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed new tag mullvad-browser-140.2.0esr-15.0-1-build2 at The Tor Project / Applications / Mullvad Browser -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/tree/mullv… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/mullvad-browser][mullvad-browser-128.14.0esr-14.5-1] 4 commits: Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed to branch mullvad-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Mullvad Browser Commits: 7d9abcbb by Tom Schuster at 2025-08-18T13:26:10+02:00 Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao Differential Revision: https://phabricator.services.mozilla.com/D256648 BB 44100: cherry-picked except tests - - - - - 46fcfe95 by Tom Schuster at 2025-08-18T13:26:12+02:00 Bug 1701974 - Use x-kde-passwordManagerHint when copying private data to the clipboard. r=stransky Differential Revision: https://phabricator.services.mozilla.com/D256781 - - - - - e710fcf4 by Tom Schuster at 2025-08-18T13:26:13+02:00 Bug 1973900 - Remove support for the codebase attribute from <object>. r=farre,dom-core Differential Revision: https://phabricator.services.mozilla.com/D254958 - - - - - 663d9707 by Kershaw Chang at 2025-08-18T13:26:15+02:00 Bug 1979955 - ensure transaction is alive (for ESR140), a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D260484 - - - - - 7 changed files: - browser/actors/ClickHandlerChild.sys.mjs - browser/app/profile/firefox.js - dom/base/nsObjectLoadingContent.cpp - modules/libpref/init/StaticPrefList.yaml - netwerk/protocol/http/nsHttpConnection.cpp - testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html - widget/gtk/nsClipboard.cpp Changes: ===================================== browser/actors/ClickHandlerChild.sys.mjs ===================================== @@ -12,12 +12,26 @@ ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs", }); +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "autoscrollEnabled", + "general.autoScroll", + true +); + +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "blockJavascript", + "browser.link.alternative_click.block_javascript", + true +); + export class MiddleMousePasteHandlerChild extends JSWindowActorChild { handleEvent(clickEvent) { if ( clickEvent.defaultPrevented || clickEvent.button != 1 || - MiddleMousePasteHandlerChild.autoscrollEnabled + lazy.autoscrollEnabled ) { return; } @@ -34,13 +48,6 @@ export class MiddleMousePasteHandlerChild extends JSWindowActorChild { } } -XPCOMUtils.defineLazyPreferenceGetter( - MiddleMousePasteHandlerChild, - "autoscrollEnabled", - "general.autoScroll", - true -); - export class ClickHandlerChild extends JSWindowActorChild { handleEvent(wrapperEvent) { this.handleClickEvent(wrapperEvent.sourceEvent); @@ -112,6 +119,14 @@ export class ClickHandlerChild extends JSWindowActorChild { }; if (href && !isFromMiddleMousePasteHandler) { + if ( + lazy.blockJavascript && + Services.io.extractScheme(href) == "javascript" + ) { + // We don't want to open new tabs or windows for javascript: links. + return; + } + try { Services.scriptSecurityManager.checkLoadURIStrWithPrincipal( principal, ===================================== browser/app/profile/firefox.js ===================================== @@ -880,6 +880,9 @@ pref("browser.link.open_newwindow.restriction", 2); pref("browser.link.open_newwindow.disabled_in_fullscreen", false); #endif +// If true, opening javscript: URLs using middle-click, CTRL+click etc. are blocked. +pref("browser.link.alternative_click.block_javascript", true); + // Tabbed browser pref("browser.tabs.closeTabByDblclick", false); pref("browser.tabs.closeWindowWithLastTab", true); ===================================== dom/base/nsObjectLoadingContent.cpp ===================================== @@ -73,6 +73,7 @@ #include "mozilla/PresShell.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/StaticPrefs_browser.h" +#include "mozilla/StaticPrefs_dom.h" #include "nsChannelClassifier.h" #include "nsFocusManager.h" #include "ReferrerInfo.h" @@ -720,11 +721,12 @@ nsObjectLoadingContent::UpdateObjectParameters() { /// Codebase /// - nsAutoString codebaseStr; nsIURI* docBaseURI = el->GetBaseURI(); - el->GetAttr(nsGkAtoms::codebase, codebaseStr); - if (!codebaseStr.IsEmpty()) { + nsAutoString codebaseStr; + el->GetAttr(nsGkAtoms::codebase, codebaseStr); + if (StaticPrefs::dom_object_embed_codebase_enabled() && + !codebaseStr.IsEmpty()) { rv = nsContentUtils::NewURIWithDocumentCharset( getter_AddRefs(newBaseURI), codebaseStr, el->OwnerDoc(), docBaseURI); if (NS_FAILED(rv)) { ===================================== modules/libpref/init/StaticPrefList.yaml ===================================== @@ -3206,6 +3206,12 @@ value: true mirror: always +# Whether the codebase attribute in an <object> is used as the base URI. +- name: dom.object_embed.codebase.enabled + type: bool + value: false + mirror: always + # Whether origin trials are enabled. - name: dom.origin-trials.enabled type: bool ===================================== netwerk/protocol/http/nsHttpConnection.cpp ===================================== @@ -1663,9 +1663,10 @@ nsresult nsHttpConnection::OnSocketWritable() { } LOG((" writing transaction request stream\n")); - rv = mTransaction->ReadSegmentsAgain(this, - nsIOService::gDefaultSegmentSize, - &transactionBytes, &again); + RefPtr<nsAHttpTransaction> transaction = mTransaction; + rv = transaction->ReadSegmentsAgain(this, + nsIOService::gDefaultSegmentSize, + &transactionBytes, &again); if (mTlsHandshaker->EarlyDataUsed()) { mContentBytesWritten0RTT += transactionBytes; if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) { @@ -1688,7 +1689,8 @@ nsresult nsHttpConnection::OnSocketWritable() { static_cast<uint32_t>(mSocketOutCondition), again)); // XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF. - if (rv == NS_BASE_STREAM_CLOSED && !mTransaction->IsDone()) { + if (rv == NS_BASE_STREAM_CLOSED && + (mTransaction && !mTransaction->IsDone())) { rv = NS_OK; transactionBytes = 0; } @@ -1731,7 +1733,8 @@ nsresult nsHttpConnection::OnSocketWritable() { // When Spdy tunnel is used we need to explicitly set when a request is // done. if ((mState != HttpConnectionState::SETTING_UP_TUNNEL) && !mSpdySession) { - nsHttpTransaction* trans = mTransaction->QueryHttpTransaction(); + nsHttpTransaction* trans = + mTransaction ? mTransaction->QueryHttpTransaction() : nullptr; // needed for websocket over h2 (direct) if (!trans || !trans->IsWebsocketUpgrade()) { mRequestDone = true; @@ -1835,7 +1838,8 @@ nsresult nsHttpConnection::OnSocketReadable() { rv = NS_ERROR_FAILURE; LOG((" No Transaction In OnSocketWritable\n")); } else { - rv = mTransaction->WriteSegmentsAgain( + RefPtr<nsAHttpTransaction> transaction = mTransaction; + rv = transaction->WriteSegmentsAgain( this, nsIOService::gDefaultSegmentSize, &n, &again); } LOG(("nsHttpConnection::OnSocketReadable %p trans->ws rv=%" PRIx32 ===================================== testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html ===================================== @@ -30,4 +30,17 @@ async_test(t => { obj.onerror = t.unreached_func(); document.body.appendChild(obj); }, "object's typemustmatch content attribute should not be supported"); + +async_test(t => { + const obj = document.createElement("object"); + t.add_cleanup(() => obj.remove()); + obj.setAttribute("data", "/common/blank.html"); + obj.setAttribute("codebase", "https://test.invalid/"); + obj.onload = t.step_func_done(() => { + assert_not_equals(obj.contentDocument, null, "/common/blank.html should be loaded"); + assert_equals(obj.contentDocument.location.origin, location.origin, "document should be loaded with current origin as base"); + }); + obj.onerror = t.unreached_func(); + document.body.appendChild(obj); +}, "object's codebase content attribute should not be supported"); </script> ===================================== widget/gtk/nsClipboard.cpp ===================================== @@ -66,6 +66,10 @@ static const char kHTMLMarkupPrefix[] = static const char kURIListMime[] = "text/uri-list"; +// MIME to exclude sensitive data (password) from the clipboard history on not +// just KDE. +static const char kKDEPasswordManagerHintMime[] = "x-kde-passwordManagerHint"; + ClipboardTargets nsRetrievalContext::sClipboardTargets; ClipboardTargets nsRetrievalContext::sPrimaryTargets; @@ -323,6 +327,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, gtk_target_list_add(list, atom, 0, 0); } + // Try to exclude private data from clipboard history. + if (aTransferable->GetIsPrivateData()) { + GdkAtom atom = gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE); + gtk_target_list_add(list, atom, 0, 0); + } + // Get GTK clipboard (CLIPBOARD or PRIMARY) GtkClipboard* gtkClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); @@ -1313,6 +1323,22 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, return; } + if (selectionTarget == gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE)) { + if (!trans->GetIsPrivateData()) { + MOZ_CLIPBOARD_LOG( + " requested %s, but the data isn't actually private!\n", + kKDEPasswordManagerHintMime); + return; + } + + static const char* kSecret = "secret"; + MOZ_CLIPBOARD_LOG(" Setting data to '%s' for %s\n", kSecret, + kKDEPasswordManagerHintMime); + gtk_selection_data_set(aSelectionData, selectionTarget, 8, + (const guchar*)kSecret, strlen(kSecret)); + return; + } + MOZ_CLIPBOARD_LOG(" Try if we have anything at GetTransferData() for %s\n", GUniquePtr<gchar>(gdk_atom_name(selectionTarget)).get()); View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/33… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/33… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.2.0esr-15.0-1] 3 commits: Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed to branch mullvad-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser Commits: da03dd1c by Tom Schuster at 2025-08-18T13:24:08+02:00 Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao Differential Revision: https://phabricator.services.mozilla.com/D256648 - - - - - 2d0f5cb1 by Tom Schuster at 2025-08-18T13:24:10+02:00 Bug 1701974 - Use x-kde-passwordManagerHint when copying private data to the clipboard. r=stransky Differential Revision: https://phabricator.services.mozilla.com/D256781 - - - - - f7cb2840 by Tom Schuster at 2025-08-18T13:24:11+02:00 Bug 1973900 - Remove support for the codebase attribute from <object>. r=farre,dom-core Differential Revision: https://phabricator.services.mozilla.com/D254958 - - - - - 11 changed files: - browser/actors/ClickHandlerChild.sys.mjs - browser/app/profile/firefox.js - browser/base/content/test/general/browser_modifiedclick_inherit_principal.js - browser/base/content/test/linkHandling/browser.toml - browser/base/content/test/linkHandling/browser_contentAreaClick_subframe_javascript.js - + browser/base/content/test/linkHandling/browser_javascript_links.js - + browser/base/content/test/linkHandling/file_javascript_links_subframe.html - dom/base/nsObjectLoadingContent.cpp - modules/libpref/init/StaticPrefList.yaml - testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html - widget/gtk/nsClipboard.cpp Changes: ===================================== browser/actors/ClickHandlerChild.sys.mjs ===================================== @@ -12,12 +12,26 @@ ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs", }); +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "autoscrollEnabled", + "general.autoScroll", + true +); + +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "blockJavascript", + "browser.link.alternative_click.block_javascript", + true +); + export class MiddleMousePasteHandlerChild extends JSWindowActorChild { handleEvent(clickEvent) { if ( clickEvent.defaultPrevented || clickEvent.button != 1 || - MiddleMousePasteHandlerChild.autoscrollEnabled + lazy.autoscrollEnabled ) { return; } @@ -34,13 +48,6 @@ export class MiddleMousePasteHandlerChild extends JSWindowActorChild { } } -XPCOMUtils.defineLazyPreferenceGetter( - MiddleMousePasteHandlerChild, - "autoscrollEnabled", - "general.autoScroll", - true -); - export class ClickHandlerChild extends JSWindowActorChild { handleEvent(wrapperEvent) { this.handleClickEvent(wrapperEvent.sourceEvent); @@ -112,6 +119,14 @@ export class ClickHandlerChild extends JSWindowActorChild { }; if (href && !isFromMiddleMousePasteHandler) { + if ( + lazy.blockJavascript && + Services.io.extractScheme(href) == "javascript" + ) { + // We don't want to open new tabs or windows for javascript: links. + return; + } + try { Services.scriptSecurityManager.checkLoadURIStrWithPrincipal( principal, ===================================== browser/app/profile/firefox.js ===================================== @@ -907,6 +907,9 @@ pref("browser.link.open_newwindow.restriction", 2); pref("browser.link.open_newwindow.disabled_in_fullscreen", false); #endif +// If true, opening javscript: URLs using middle-click, CTRL+click etc. are blocked. +pref("browser.link.alternative_click.block_javascript", true); + // Tabbed browser pref("browser.tabs.closeTabByDblclick", false); pref("browser.tabs.closeWindowWithLastTab", true); ===================================== browser/base/content/test/general/browser_modifiedclick_inherit_principal.js ===================================== @@ -10,6 +10,10 @@ const kURL = * we use the correct principal, and we don't clear the URL bar. */ add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["browser.link.alternative_click.block_javascript", false]], + }); + await BrowserTestUtils.withNewTab(kURL, async function (browser) { let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser); await SpecialPowers.spawn(browser, [], async function () { ===================================== browser/base/content/test/linkHandling/browser.toml ===================================== @@ -2,3 +2,8 @@ support-files = [ "file_contentAreaClick_subframe_javascript.html" ] + +["browser_javascript_links.js"] +support-files = [ + "file_javascript_links_subframe.html" +] ===================================== browser/base/content/test/linkHandling/browser_contentAreaClick_subframe_javascript.js ===================================== @@ -5,6 +5,10 @@ const gExampleComRoot = getRootDirectory(gTestPath).replace( const IFRAME_FILE = "file_contentAreaClick_subframe_javascript.html"; add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["browser.link.alternative_click.block_javascript", false]], + }); + await BrowserTestUtils.withNewTab( `data:text/html,<iframe src="${gExampleComRoot + IFRAME_FILE}"></iframe>`, async browser => { ===================================== browser/base/content/test/linkHandling/browser_javascript_links.js ===================================== @@ -0,0 +1,88 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content/", + "https://example.com/" +); +const IFRAME_PATH = TEST_PATH + "file_javascript_links_subframe.html"; + +add_setup(async function () { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.link.alternative_click.block_javascript", true], + ["browser.tabs.opentabfor.middleclick", true], + ["middlemouse.paste", false], + ["middlemouse.contentLoadURL", false], + ["general.autoScroll", false], + ], + }); +}); + +add_task(async function () { + await BrowserTestUtils.withNewTab( + `data:text/html,<a href="javascript:alert(1);">click me`, + async browser => { + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { button: 0, ctrlKey: true, metaKey: true }, + browser + ); + is( + gBrowser.tabs.length, + 2, + "Accel+click on javascript: link shouldn't open a new tab" + ); + + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { button: 1 }, + browser + ); + is( + gBrowser.tabs.length, + 2, + "Middle click on javascript: link shouldn't open a new tab" + ); + + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { button: 0, shiftKey: true }, + browser + ); + // This is fragile and might miss the new window, but the test will fail + // anyway when finishing with an extra window left behind. + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(resolve => setTimeout(resolve, 200)); + is( + BrowserWindowTracker.windowCount, + 1, + "Shift+click on javascript: link shouldn't open a new window" + ); + } + ); +}); + +add_task(async function iframe_link() { + await BrowserTestUtils.withNewTab( + `data:text/html,<iframe src="${IFRAME_PATH}"></iframe>`, + async browser => { + // ctrl/cmd-click the link in the subframe. + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { ctrlKey: true, metaKey: true }, + browser.browsingContext.children[0] + ); + + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(resolve => setTimeout(resolve, 200)); + is( + gBrowser.tabs.length, + 2, + "Click on javascript: link in iframe shouldn't open a new tab" + ); + } + ); +}); ===================================== browser/base/content/test/linkHandling/file_javascript_links_subframe.html ===================================== @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<a href="javascript:alert(1)">click me ===================================== dom/base/nsObjectLoadingContent.cpp ===================================== @@ -73,6 +73,7 @@ #include "mozilla/PresShell.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/StaticPrefs_browser.h" +#include "mozilla/StaticPrefs_dom.h" #include "nsChannelClassifier.h" #include "nsFocusManager.h" #include "ReferrerInfo.h" @@ -736,11 +737,12 @@ nsObjectLoadingContent::UpdateObjectParameters() { /// Codebase /// - nsAutoString codebaseStr; nsIURI* docBaseURI = el->GetBaseURI(); - el->GetAttr(nsGkAtoms::codebase, codebaseStr); - if (!codebaseStr.IsEmpty()) { + nsAutoString codebaseStr; + el->GetAttr(nsGkAtoms::codebase, codebaseStr); + if (StaticPrefs::dom_object_embed_codebase_enabled() && + !codebaseStr.IsEmpty()) { rv = nsContentUtils::NewURIWithDocumentCharset( getter_AddRefs(newBaseURI), codebaseStr, el->OwnerDoc(), docBaseURI); if (NS_FAILED(rv)) { ===================================== modules/libpref/init/StaticPrefList.yaml ===================================== @@ -3633,6 +3633,12 @@ value: true mirror: always +# Whether the codebase attribute in an <object> is used as the base URI. +- name: dom.object_embed.codebase.enabled + type: bool + value: false + mirror: always + # Whether origin trials are enabled. - name: dom.origin-trials.enabled type: bool ===================================== testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html ===================================== @@ -30,4 +30,17 @@ async_test(t => { obj.onerror = t.unreached_func(); document.body.appendChild(obj); }, "object's typemustmatch content attribute should not be supported"); + +async_test(t => { + const obj = document.createElement("object"); + t.add_cleanup(() => obj.remove()); + obj.setAttribute("data", "/common/blank.html"); + obj.setAttribute("codebase", "https://test.invalid/"); + obj.onload = t.step_func_done(() => { + assert_not_equals(obj.contentDocument, null, "/common/blank.html should be loaded"); + assert_equals(obj.contentDocument.location.origin, location.origin, "document should be loaded with current origin as base"); + }); + obj.onerror = t.unreached_func(); + document.body.appendChild(obj); +}, "object's codebase content attribute should not be supported"); </script> ===================================== widget/gtk/nsClipboard.cpp ===================================== @@ -66,6 +66,10 @@ static const char kHTMLMarkupPrefix[] = static const char kURIListMime[] = "text/uri-list"; +// MIME to exclude sensitive data (password) from the clipboard history on not +// just KDE. +static const char kKDEPasswordManagerHintMime[] = "x-kde-passwordManagerHint"; + MOZ_CONSTINIT ClipboardTargets nsRetrievalContext::sClipboardTargets; MOZ_CONSTINIT ClipboardTargets nsRetrievalContext::sPrimaryTargets; @@ -313,6 +317,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, gtk_target_list_add(list, atom, 0, 0); } + // Try to exclude private data from clipboard history. + if (aTransferable->GetIsPrivateData()) { + GdkAtom atom = gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE); + gtk_target_list_add(list, atom, 0, 0); + } + // Get GTK clipboard (CLIPBOARD or PRIMARY) GtkClipboard* gtkClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); @@ -1228,6 +1238,22 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, return; } + if (selectionTarget == gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE)) { + if (!trans->GetIsPrivateData()) { + MOZ_CLIPBOARD_LOG( + " requested %s, but the data isn't actually private!\n", + kKDEPasswordManagerHintMime); + return; + } + + static const char* kSecret = "secret"; + MOZ_CLIPBOARD_LOG(" Setting data to '%s' for %s\n", kSecret, + kKDEPasswordManagerHintMime); + gtk_selection_data_set(aSelectionData, selectionTarget, 8, + (const guchar*)kSecret, strlen(kSecret)); + return; + } + MOZ_CLIPBOARD_LOG(" Try if we have anything at GetTransferData() for %s\n", GUniquePtr<gchar>(gdk_atom_name(selectionTarget)).get()); View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/ed… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/ed… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser] Pushed new tag tor-browser-140.2.0esr-15.0-1-build2
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed new tag tor-browser-140.2.0esr-15.0-1-build2 at The Tor Project / Applications / Tor Browser -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/tor-brows… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser] Pushed new tag tor-browser-128.14.0esr-14.5-1-build2
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed new tag tor-browser-128.14.0esr-14.5-1-build2 at The Tor Project / Applications / Tor Browser -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/tor-brows… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-128.14.0esr-14.5-1] 4 commits: Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed to branch tor-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser Commits: 7eff61f4 by Tom Schuster at 2025-08-17T23:15:21+02:00 Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao Differential Revision: https://phabricator.services.mozilla.com/D256648 BB 44100: cherry-picked except tests - - - - - 68a8c0b1 by Tom Schuster at 2025-08-17T23:44:16+02:00 Bug 1701974 - Use x-kde-passwordManagerHint when copying private data to the clipboard. r=stransky Differential Revision: https://phabricator.services.mozilla.com/D256781 - - - - - c97ea93d by Tom Schuster at 2025-08-18T10:06:51+02:00 Bug 1973900 - Remove support for the codebase attribute from <object>. r=farre,dom-core Differential Revision: https://phabricator.services.mozilla.com/D254958 - - - - - c5a292c1 by Kershaw Chang at 2025-08-18T10:30:17+02:00 Bug 1979955 - ensure transaction is alive (for ESR140), a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D260484 - - - - - 7 changed files: - browser/actors/ClickHandlerChild.sys.mjs - browser/app/profile/firefox.js - dom/base/nsObjectLoadingContent.cpp - modules/libpref/init/StaticPrefList.yaml - netwerk/protocol/http/nsHttpConnection.cpp - testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html - widget/gtk/nsClipboard.cpp Changes: ===================================== browser/actors/ClickHandlerChild.sys.mjs ===================================== @@ -12,12 +12,26 @@ ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs", }); +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "autoscrollEnabled", + "general.autoScroll", + true +); + +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "blockJavascript", + "browser.link.alternative_click.block_javascript", + true +); + export class MiddleMousePasteHandlerChild extends JSWindowActorChild { handleEvent(clickEvent) { if ( clickEvent.defaultPrevented || clickEvent.button != 1 || - MiddleMousePasteHandlerChild.autoscrollEnabled + lazy.autoscrollEnabled ) { return; } @@ -34,13 +48,6 @@ export class MiddleMousePasteHandlerChild extends JSWindowActorChild { } } -XPCOMUtils.defineLazyPreferenceGetter( - MiddleMousePasteHandlerChild, - "autoscrollEnabled", - "general.autoScroll", - true -); - export class ClickHandlerChild extends JSWindowActorChild { handleEvent(wrapperEvent) { this.handleClickEvent(wrapperEvent.sourceEvent); @@ -112,6 +119,14 @@ export class ClickHandlerChild extends JSWindowActorChild { }; if (href && !isFromMiddleMousePasteHandler) { + if ( + lazy.blockJavascript && + Services.io.extractScheme(href) == "javascript" + ) { + // We don't want to open new tabs or windows for javascript: links. + return; + } + try { Services.scriptSecurityManager.checkLoadURIStrWithPrincipal( principal, ===================================== browser/app/profile/firefox.js ===================================== @@ -880,6 +880,9 @@ pref("browser.link.open_newwindow.restriction", 2); pref("browser.link.open_newwindow.disabled_in_fullscreen", false); #endif +// If true, opening javscript: URLs using middle-click, CTRL+click etc. are blocked. +pref("browser.link.alternative_click.block_javascript", true); + // Tabbed browser pref("browser.tabs.closeTabByDblclick", false); pref("browser.tabs.closeWindowWithLastTab", true); ===================================== dom/base/nsObjectLoadingContent.cpp ===================================== @@ -73,6 +73,7 @@ #include "mozilla/PresShell.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/StaticPrefs_browser.h" +#include "mozilla/StaticPrefs_dom.h" #include "nsChannelClassifier.h" #include "nsFocusManager.h" #include "ReferrerInfo.h" @@ -720,11 +721,12 @@ nsObjectLoadingContent::UpdateObjectParameters() { /// Codebase /// - nsAutoString codebaseStr; nsIURI* docBaseURI = el->GetBaseURI(); - el->GetAttr(nsGkAtoms::codebase, codebaseStr); - if (!codebaseStr.IsEmpty()) { + nsAutoString codebaseStr; + el->GetAttr(nsGkAtoms::codebase, codebaseStr); + if (StaticPrefs::dom_object_embed_codebase_enabled() && + !codebaseStr.IsEmpty()) { rv = nsContentUtils::NewURIWithDocumentCharset( getter_AddRefs(newBaseURI), codebaseStr, el->OwnerDoc(), docBaseURI); if (NS_FAILED(rv)) { ===================================== modules/libpref/init/StaticPrefList.yaml ===================================== @@ -3214,6 +3214,12 @@ value: true mirror: always +# Whether the codebase attribute in an <object> is used as the base URI. +- name: dom.object_embed.codebase.enabled + type: bool + value: false + mirror: always + # Whether origin trials are enabled. - name: dom.origin-trials.enabled type: bool ===================================== netwerk/protocol/http/nsHttpConnection.cpp ===================================== @@ -1663,9 +1663,10 @@ nsresult nsHttpConnection::OnSocketWritable() { } LOG((" writing transaction request stream\n")); - rv = mTransaction->ReadSegmentsAgain(this, - nsIOService::gDefaultSegmentSize, - &transactionBytes, &again); + RefPtr<nsAHttpTransaction> transaction = mTransaction; + rv = transaction->ReadSegmentsAgain(this, + nsIOService::gDefaultSegmentSize, + &transactionBytes, &again); if (mTlsHandshaker->EarlyDataUsed()) { mContentBytesWritten0RTT += transactionBytes; if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) { @@ -1688,7 +1689,8 @@ nsresult nsHttpConnection::OnSocketWritable() { static_cast<uint32_t>(mSocketOutCondition), again)); // XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF. - if (rv == NS_BASE_STREAM_CLOSED && !mTransaction->IsDone()) { + if (rv == NS_BASE_STREAM_CLOSED && + (mTransaction && !mTransaction->IsDone())) { rv = NS_OK; transactionBytes = 0; } @@ -1731,7 +1733,8 @@ nsresult nsHttpConnection::OnSocketWritable() { // When Spdy tunnel is used we need to explicitly set when a request is // done. if ((mState != HttpConnectionState::SETTING_UP_TUNNEL) && !mSpdySession) { - nsHttpTransaction* trans = mTransaction->QueryHttpTransaction(); + nsHttpTransaction* trans = + mTransaction ? mTransaction->QueryHttpTransaction() : nullptr; // needed for websocket over h2 (direct) if (!trans || !trans->IsWebsocketUpgrade()) { mRequestDone = true; @@ -1835,7 +1838,8 @@ nsresult nsHttpConnection::OnSocketReadable() { rv = NS_ERROR_FAILURE; LOG((" No Transaction In OnSocketWritable\n")); } else { - rv = mTransaction->WriteSegmentsAgain( + RefPtr<nsAHttpTransaction> transaction = mTransaction; + rv = transaction->WriteSegmentsAgain( this, nsIOService::gDefaultSegmentSize, &n, &again); } LOG(("nsHttpConnection::OnSocketReadable %p trans->ws rv=%" PRIx32 ===================================== testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html ===================================== @@ -30,4 +30,17 @@ async_test(t => { obj.onerror = t.unreached_func(); document.body.appendChild(obj); }, "object's typemustmatch content attribute should not be supported"); + +async_test(t => { + const obj = document.createElement("object"); + t.add_cleanup(() => obj.remove()); + obj.setAttribute("data", "/common/blank.html"); + obj.setAttribute("codebase", "https://test.invalid/"); + obj.onload = t.step_func_done(() => { + assert_not_equals(obj.contentDocument, null, "/common/blank.html should be loaded"); + assert_equals(obj.contentDocument.location.origin, location.origin, "document should be loaded with current origin as base"); + }); + obj.onerror = t.unreached_func(); + document.body.appendChild(obj); +}, "object's codebase content attribute should not be supported"); </script> ===================================== widget/gtk/nsClipboard.cpp ===================================== @@ -66,6 +66,10 @@ static const char kHTMLMarkupPrefix[] = static const char kURIListMime[] = "text/uri-list"; +// MIME to exclude sensitive data (password) from the clipboard history on not +// just KDE. +static const char kKDEPasswordManagerHintMime[] = "x-kde-passwordManagerHint"; + ClipboardTargets nsRetrievalContext::sClipboardTargets; ClipboardTargets nsRetrievalContext::sPrimaryTargets; @@ -323,6 +327,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, gtk_target_list_add(list, atom, 0, 0); } + // Try to exclude private data from clipboard history. + if (aTransferable->GetIsPrivateData()) { + GdkAtom atom = gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE); + gtk_target_list_add(list, atom, 0, 0); + } + // Get GTK clipboard (CLIPBOARD or PRIMARY) GtkClipboard* gtkClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); @@ -1313,6 +1323,22 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, return; } + if (selectionTarget == gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE)) { + if (!trans->GetIsPrivateData()) { + MOZ_CLIPBOARD_LOG( + " requested %s, but the data isn't actually private!\n", + kKDEPasswordManagerHintMime); + return; + } + + static const char* kSecret = "secret"; + MOZ_CLIPBOARD_LOG(" Setting data to '%s' for %s\n", kSecret, + kKDEPasswordManagerHintMime); + gtk_selection_data_set(aSelectionData, selectionTarget, 8, + (const guchar*)kSecret, strlen(kSecret)); + return; + } + MOZ_CLIPBOARD_LOG(" Try if we have anything at GetTransferData() for %s\n", GUniquePtr<gchar>(gdk_atom_name(selectionTarget)).get()); View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/44c35e… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/44c35e… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-140.2.0esr-15.0-1] 3 commits: Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao
by ma1 (@ma1) 18 Aug '25

18 Aug '25
ma1 pushed to branch tor-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser Commits: 1e27e250 by Tom Schuster at 2025-08-17T23:24:32+02:00 Bug 672618 - Don't execute javascript: URLs on CTRL+click, middle-click etc. r=dao Differential Revision: https://phabricator.services.mozilla.com/D256648 - - - - - 15852030 by Tom Schuster at 2025-08-17T23:33:51+02:00 Bug 1701974 - Use x-kde-passwordManagerHint when copying private data to the clipboard. r=stransky Differential Revision: https://phabricator.services.mozilla.com/D256781 - - - - - 1fcba6b6 by Tom Schuster at 2025-08-18T10:13:32+02:00 Bug 1973900 - Remove support for the codebase attribute from <object>. r=farre,dom-core Differential Revision: https://phabricator.services.mozilla.com/D254958 - - - - - 11 changed files: - browser/actors/ClickHandlerChild.sys.mjs - browser/app/profile/firefox.js - browser/base/content/test/general/browser_modifiedclick_inherit_principal.js - browser/base/content/test/linkHandling/browser.toml - browser/base/content/test/linkHandling/browser_contentAreaClick_subframe_javascript.js - + browser/base/content/test/linkHandling/browser_javascript_links.js - + browser/base/content/test/linkHandling/file_javascript_links_subframe.html - dom/base/nsObjectLoadingContent.cpp - modules/libpref/init/StaticPrefList.yaml - testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html - widget/gtk/nsClipboard.cpp Changes: ===================================== browser/actors/ClickHandlerChild.sys.mjs ===================================== @@ -12,12 +12,26 @@ ChromeUtils.defineESModuleGetters(lazy, { E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs", }); +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "autoscrollEnabled", + "general.autoScroll", + true +); + +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "blockJavascript", + "browser.link.alternative_click.block_javascript", + true +); + export class MiddleMousePasteHandlerChild extends JSWindowActorChild { handleEvent(clickEvent) { if ( clickEvent.defaultPrevented || clickEvent.button != 1 || - MiddleMousePasteHandlerChild.autoscrollEnabled + lazy.autoscrollEnabled ) { return; } @@ -34,13 +48,6 @@ export class MiddleMousePasteHandlerChild extends JSWindowActorChild { } } -XPCOMUtils.defineLazyPreferenceGetter( - MiddleMousePasteHandlerChild, - "autoscrollEnabled", - "general.autoScroll", - true -); - export class ClickHandlerChild extends JSWindowActorChild { handleEvent(wrapperEvent) { this.handleClickEvent(wrapperEvent.sourceEvent); @@ -112,6 +119,14 @@ export class ClickHandlerChild extends JSWindowActorChild { }; if (href && !isFromMiddleMousePasteHandler) { + if ( + lazy.blockJavascript && + Services.io.extractScheme(href) == "javascript" + ) { + // We don't want to open new tabs or windows for javascript: links. + return; + } + try { Services.scriptSecurityManager.checkLoadURIStrWithPrincipal( principal, ===================================== browser/app/profile/firefox.js ===================================== @@ -907,6 +907,9 @@ pref("browser.link.open_newwindow.restriction", 2); pref("browser.link.open_newwindow.disabled_in_fullscreen", false); #endif +// If true, opening javscript: URLs using middle-click, CTRL+click etc. are blocked. +pref("browser.link.alternative_click.block_javascript", true); + // Tabbed browser pref("browser.tabs.closeTabByDblclick", false); pref("browser.tabs.closeWindowWithLastTab", true); ===================================== browser/base/content/test/general/browser_modifiedclick_inherit_principal.js ===================================== @@ -10,6 +10,10 @@ const kURL = * we use the correct principal, and we don't clear the URL bar. */ add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["browser.link.alternative_click.block_javascript", false]], + }); + await BrowserTestUtils.withNewTab(kURL, async function (browser) { let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser); await SpecialPowers.spawn(browser, [], async function () { ===================================== browser/base/content/test/linkHandling/browser.toml ===================================== @@ -2,3 +2,8 @@ support-files = [ "file_contentAreaClick_subframe_javascript.html" ] + +["browser_javascript_links.js"] +support-files = [ + "file_javascript_links_subframe.html" +] ===================================== browser/base/content/test/linkHandling/browser_contentAreaClick_subframe_javascript.js ===================================== @@ -5,6 +5,10 @@ const gExampleComRoot = getRootDirectory(gTestPath).replace( const IFRAME_FILE = "file_contentAreaClick_subframe_javascript.html"; add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["browser.link.alternative_click.block_javascript", false]], + }); + await BrowserTestUtils.withNewTab( `data:text/html,<iframe src="${gExampleComRoot + IFRAME_FILE}"></iframe>`, async browser => { ===================================== browser/base/content/test/linkHandling/browser_javascript_links.js ===================================== @@ -0,0 +1,88 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content/", + "https://example.com/" +); +const IFRAME_PATH = TEST_PATH + "file_javascript_links_subframe.html"; + +add_setup(async function () { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.link.alternative_click.block_javascript", true], + ["browser.tabs.opentabfor.middleclick", true], + ["middlemouse.paste", false], + ["middlemouse.contentLoadURL", false], + ["general.autoScroll", false], + ], + }); +}); + +add_task(async function () { + await BrowserTestUtils.withNewTab( + `data:text/html,<a href="javascript:alert(1);">click me`, + async browser => { + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { button: 0, ctrlKey: true, metaKey: true }, + browser + ); + is( + gBrowser.tabs.length, + 2, + "Accel+click on javascript: link shouldn't open a new tab" + ); + + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { button: 1 }, + browser + ); + is( + gBrowser.tabs.length, + 2, + "Middle click on javascript: link shouldn't open a new tab" + ); + + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { button: 0, shiftKey: true }, + browser + ); + // This is fragile and might miss the new window, but the test will fail + // anyway when finishing with an extra window left behind. + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(resolve => setTimeout(resolve, 200)); + is( + BrowserWindowTracker.windowCount, + 1, + "Shift+click on javascript: link shouldn't open a new window" + ); + } + ); +}); + +add_task(async function iframe_link() { + await BrowserTestUtils.withNewTab( + `data:text/html,<iframe src="${IFRAME_PATH}"></iframe>`, + async browser => { + // ctrl/cmd-click the link in the subframe. + await BrowserTestUtils.synthesizeMouseAtCenter( + "a", + { ctrlKey: true, metaKey: true }, + browser.browsingContext.children[0] + ); + + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(resolve => setTimeout(resolve, 200)); + is( + gBrowser.tabs.length, + 2, + "Click on javascript: link in iframe shouldn't open a new tab" + ); + } + ); +}); ===================================== browser/base/content/test/linkHandling/file_javascript_links_subframe.html ===================================== @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<a href="javascript:alert(1)">click me ===================================== dom/base/nsObjectLoadingContent.cpp ===================================== @@ -73,6 +73,7 @@ #include "mozilla/PresShell.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/StaticPrefs_browser.h" +#include "mozilla/StaticPrefs_dom.h" #include "nsChannelClassifier.h" #include "nsFocusManager.h" #include "ReferrerInfo.h" @@ -736,11 +737,12 @@ nsObjectLoadingContent::UpdateObjectParameters() { /// Codebase /// - nsAutoString codebaseStr; nsIURI* docBaseURI = el->GetBaseURI(); - el->GetAttr(nsGkAtoms::codebase, codebaseStr); - if (!codebaseStr.IsEmpty()) { + nsAutoString codebaseStr; + el->GetAttr(nsGkAtoms::codebase, codebaseStr); + if (StaticPrefs::dom_object_embed_codebase_enabled() && + !codebaseStr.IsEmpty()) { rv = nsContentUtils::NewURIWithDocumentCharset( getter_AddRefs(newBaseURI), codebaseStr, el->OwnerDoc(), docBaseURI); if (NS_FAILED(rv)) { ===================================== modules/libpref/init/StaticPrefList.yaml ===================================== @@ -3641,6 +3641,12 @@ value: true mirror: always +# Whether the codebase attribute in an <object> is used as the base URI. +- name: dom.object_embed.codebase.enabled + type: bool + value: false + mirror: always + # Whether origin trials are enabled. - name: dom.origin-trials.enabled type: bool ===================================== testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html ===================================== @@ -30,4 +30,17 @@ async_test(t => { obj.onerror = t.unreached_func(); document.body.appendChild(obj); }, "object's typemustmatch content attribute should not be supported"); + +async_test(t => { + const obj = document.createElement("object"); + t.add_cleanup(() => obj.remove()); + obj.setAttribute("data", "/common/blank.html"); + obj.setAttribute("codebase", "https://test.invalid/"); + obj.onload = t.step_func_done(() => { + assert_not_equals(obj.contentDocument, null, "/common/blank.html should be loaded"); + assert_equals(obj.contentDocument.location.origin, location.origin, "document should be loaded with current origin as base"); + }); + obj.onerror = t.unreached_func(); + document.body.appendChild(obj); +}, "object's codebase content attribute should not be supported"); </script> ===================================== widget/gtk/nsClipboard.cpp ===================================== @@ -66,6 +66,10 @@ static const char kHTMLMarkupPrefix[] = static const char kURIListMime[] = "text/uri-list"; +// MIME to exclude sensitive data (password) from the clipboard history on not +// just KDE. +static const char kKDEPasswordManagerHintMime[] = "x-kde-passwordManagerHint"; + MOZ_CONSTINIT ClipboardTargets nsRetrievalContext::sClipboardTargets; MOZ_CONSTINIT ClipboardTargets nsRetrievalContext::sPrimaryTargets; @@ -313,6 +317,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, gtk_target_list_add(list, atom, 0, 0); } + // Try to exclude private data from clipboard history. + if (aTransferable->GetIsPrivateData()) { + GdkAtom atom = gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE); + gtk_target_list_add(list, atom, 0, 0); + } + // Get GTK clipboard (CLIPBOARD or PRIMARY) GtkClipboard* gtkClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); @@ -1228,6 +1238,22 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, return; } + if (selectionTarget == gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE)) { + if (!trans->GetIsPrivateData()) { + MOZ_CLIPBOARD_LOG( + " requested %s, but the data isn't actually private!\n", + kKDEPasswordManagerHintMime); + return; + } + + static const char* kSecret = "secret"; + MOZ_CLIPBOARD_LOG(" Setting data to '%s' for %s\n", kSecret, + kKDEPasswordManagerHintMime); + gtk_selection_data_set(aSelectionData, selectionTarget, 8, + (const guchar*)kSecret, strlen(kSecret)); + return; + } + MOZ_CLIPBOARD_LOG(" Try if we have anything at GetTransferData() for %s\n", GUniquePtr<gchar>(gdk_atom_name(selectionTarget)).get()); View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/4169e5… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/4169e5… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • ...
  • 20
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.