tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 1dfcfb33ff21df577004c49b280bd82da17a1565
parent 985c5a4d6619cbdd890efbef9c7bb52a148c0cc1
Author: Andrea Marchesini <amarchesini@mozilla.com>
Date:   Wed,  3 Dec 2025 21:12:49 +0000

Bug 1986320 - Implement an add-on block URL-Classifier feature - part 6 - Mobile r=geckoview-reviewers,android-reviewers,geckoview-api-reviewers,tcampbell,ohall

Differential Revision: https://phabricator.services.mozilla.com/D274424

Diffstat:
Mmobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt | 1+
Mmobile/android/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt | 5+++++
Mmobile/android/android-components/components/browser/errorpages/src/main/java/mozilla/components/browser/errorpages/ErrorPages.kt | 2+-
Mmobile/android/android-components/components/browser/errorpages/src/test/java/mozilla/components/browser/errorpages/ErrorPagesTest.kt | 1+
Mmobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/EngineSession.kt | 7++++++-
Mmobile/android/app/geckoview-prefs.js | 1+
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/AppRequestInterceptor.kt | 1+
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt | 1+
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/AppRequestInterceptorTest.kt | 1+
Mmobile/android/geckoview/api.txt | 4+++-
Mmobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java | 31++++++++++++++++++++++++++++---
Mmobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebRequestError.java | 7+++++++
Mmobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md | 8+++++++-
Mmobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java | 2++
Mmobile/shared/modules/geckoview/LoadURIDelegate.sys.mjs | 3++-
15 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/mobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt b/mobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt @@ -1624,6 +1624,7 @@ class GeckoEngineSession( WebRequestError.ERROR_SAFEBROWSING_UNWANTED_URI -> ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI WebRequestError.ERROR_SAFEBROWSING_HARMFUL_URI -> ErrorType.ERROR_SAFEBROWSING_HARMFUL_URI WebRequestError.ERROR_SAFEBROWSING_PHISHING_URI -> ErrorType.ERROR_SAFEBROWSING_PHISHING_URI + WebRequestError.ERROR_HARMFULADDON_URI -> ErrorType.ERROR_HARMFULADDON_URI WebRequestError.ERROR_HTTPS_ONLY -> ErrorType.ERROR_HTTPS_ONLY WebRequestError.ERROR_BAD_HSTS_CERT -> ErrorType.ERROR_BAD_HSTS_CERT else -> ErrorType.UNKNOWN diff --git a/mobile/android/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt b/mobile/android/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt @@ -1816,6 +1816,7 @@ class GeckoEngineSessionTest { assertEquals(GeckoSafeBrowsing.UNWANTED, SafeBrowsingPolicy.UNWANTED.id) assertEquals(GeckoSafeBrowsing.HARMFUL, SafeBrowsingPolicy.HARMFUL.id) assertEquals(GeckoSafeBrowsing.PHISHING, SafeBrowsingPolicy.PHISHING.id) + assertEquals(GeckoSafeBrowsing.HARMFULADDON, SafeBrowsingPolicy.HARMFULADDON.id) assertEquals(GeckoSafeBrowsing.DEFAULT, SafeBrowsingPolicy.RECOMMENDED.id) } @@ -2337,6 +2338,10 @@ class GeckoEngineSessionTest { GeckoEngineSession.geckoErrorToErrorType(WebRequestError.ERROR_SAFEBROWSING_UNWANTED_URI), ) assertEquals( + ErrorType.ERROR_HARMFULADDON_URI, + GeckoEngineSession.geckoErrorToErrorType(WebRequestError.ERROR_HARMFULADDON_URI), + ) + assertEquals( ErrorType.UNKNOWN, GeckoEngineSession.geckoErrorToErrorType(-500), ) diff --git a/mobile/android/android-components/components/browser/errorpages/src/main/java/mozilla/components/browser/errorpages/ErrorPages.kt b/mobile/android/android-components/components/browser/errorpages/src/main/java/mozilla/components/browser/errorpages/ErrorPages.kt @@ -240,7 +240,7 @@ enum class ErrorType( R.string.mozac_browser_errorpages_safe_phishing_uri_title, R.string.mozac_browser_errorpages_safe_phishing_uri_message, ), - NS_ERROR_HARMFULADDON_URI( + ERROR_HARMFULADDON_URI( R.string.mozac_browser_errorpages_harmful_addon_uri_title, R.string.mozac_browser_errorpages_harmful_addon_uri_message, ), diff --git a/mobile/android/android-components/components/browser/errorpages/src/test/java/mozilla/components/browser/errorpages/ErrorPagesTest.kt b/mobile/android/android-components/components/browser/errorpages/src/test/java/mozilla/components/browser/errorpages/ErrorPagesTest.kt @@ -74,6 +74,7 @@ class ErrorPagesTest { assertUrlEncodingIsValid(ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI) assertUrlEncodingIsValid(ErrorType.ERROR_SAFEBROWSING_HARMFUL_URI) assertUrlEncodingIsValid(ErrorType.ERROR_SAFEBROWSING_PHISHING_URI) + assertUrlEncodingIsValid(ErrorType.ERROR_HARMFULADDON_URI) assertUrlEncodingIsValid(ErrorType.ERROR_HTTPS_ONLY) assertUrlEncodingIsValid(ErrorType.ERROR_BAD_HSTS_CERT) } diff --git a/mobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/EngineSession.kt b/mobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/EngineSession.kt @@ -430,9 +430,14 @@ abstract class EngineSession( PHISHING(1 shl 13), /** + * Blocks harmful add-on sites. + */ + HARMFULADDON(1 shl 14), + + /** * Blocks all unsafe sites. */ - RECOMMENDED(MALWARE.id + UNWANTED.id + HARMFUL.id + PHISHING.id), + RECOMMENDED(MALWARE.id + UNWANTED.id + HARMFUL.id + PHISHING.id + HARMFULADDON.id), } /** diff --git a/mobile/android/app/geckoview-prefs.js b/mobile/android/app/geckoview-prefs.js @@ -111,6 +111,7 @@ pref("browser.meta_refresh_when_inactive.disabled", true); // The download protection UI is not implemented yet (bug 1239094). pref("browser.safebrowsing.downloads.enabled", false); +pref("browser.safebrowsing.features.harmfuladdon.update", true); pref("browser.safebrowsing.features.cryptomining.update", true); pref("browser.safebrowsing.features.fingerprinting.update", true); pref("browser.safebrowsing.features.malware.update", true); diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/AppRequestInterceptor.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/AppRequestInterceptor.kt @@ -165,6 +165,7 @@ class AppRequestInterceptor( ErrorType.ERROR_SAFEBROWSING_MALWARE_URI, ErrorType.ERROR_SAFEBROWSING_PHISHING_URI, ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI, + ErrorType.ERROR_HARMFULADDON_URI, -> RiskLevel.High } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt @@ -163,6 +163,7 @@ class AppRequestInterceptor( ErrorType.ERROR_SAFEBROWSING_MALWARE_URI, ErrorType.ERROR_SAFEBROWSING_PHISHING_URI, ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI, + ErrorType.ERROR_HARMFULADDON_URI, -> RiskLevel.High } diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/AppRequestInterceptorTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/AppRequestInterceptorTest.kt @@ -186,6 +186,7 @@ class AppRequestInterceptorTest { ErrorType.ERROR_SAFEBROWSING_MALWARE_URI, ErrorType.ERROR_SAFEBROWSING_PHISHING_URI, ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI, + ErrorType.ERROR_HARMFULADDON_URI, ).forEach { error -> val actualPage = createActualErrorPage(error) val expectedPage = createExpectedErrorPage( diff --git a/mobile/android/geckoview/api.txt b/mobile/android/geckoview/api.txt @@ -543,8 +543,9 @@ package org.mozilla.geckoview { public static class ContentBlocking.SafeBrowsing { ctor protected SafeBrowsing(); - field public static final int DEFAULT = 15360; + field public static final int DEFAULT = 31744; field public static final int HARMFUL = 4096; + field public static final int HARMFULADDON = 16384; field public static final int MALWARE = 1024; field public static final int NONE = 0; field public static final int PHISHING = 8192; @@ -3120,6 +3121,7 @@ package org.mozilla.geckoview { field public static final int ERROR_DATA_URI_TOO_LONG = 117; field public static final int ERROR_FILE_ACCESS_DENIED = 101; field public static final int ERROR_FILE_NOT_FOUND = 85; + field public static final int ERROR_HARMFULADDON_URI = 103; field public static final int ERROR_HTTPS_ONLY = 163; field public static final int ERROR_INVALID_CONTENT_ENCODING = 84; field public static final int ERROR_MALFORMED_URI = 53; diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java @@ -447,6 +447,8 @@ public class ContentBlocking { new Pref<Boolean>("browser.safebrowsing.malware.enabled", true); /* package */ final Pref<Boolean> mSbPhishing = new Pref<Boolean>("browser.safebrowsing.phishing.enabled", true); + /* package */ final Pref<Boolean> mSbHarmfulAddon = + new Pref<Boolean>("privacy.trackingprotection.harmfuladdon.enabled", true); /* package */ final Pref<Integer> mCookieBehavior = new Pref<Integer>( "network.cookie.cookieBehavior", CookieBehavior.ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS); @@ -516,6 +518,11 @@ public class ContentBlocking { "urlclassifier.features.emailtracking.blocklistTables", ContentBlocking.catToPref(AntiTracking.NONE, AntiTracking.EMAIL, EMAIL)); + /* package */ final Pref<String> mSbHarmfulAddonList = + new Pref<String>( + "urlclassifier.features.harmfuladdon.blocklistTables", + ContentBlocking.catToPref(AntiTracking.NONE, SafeBrowsing.HARMFULADDON, HARMFULADDON)); + /* package */ final Pref<String> mSafeBrowsingMalwareTable = new Pref<>( "urlclassifier.malwareTable", @@ -823,6 +830,7 @@ public class ContentBlocking { public @NonNull Settings setSafeBrowsing(final @CBSafeBrowsing int cat) { mSbMalware.commit(ContentBlocking.catToSbMalware(cat)); mSbPhishing.commit(ContentBlocking.catToSbPhishing(cat)); + mSbHarmfulAddon.commit(ContentBlocking.catToSbHarmfulAddon(cat)); return this; } @@ -885,7 +893,8 @@ public class ContentBlocking { */ public @CBSafeBrowsing int getSafeBrowsingCategories() { return ContentBlocking.sbMalwareToSbCat(mSbMalware.get()) - | ContentBlocking.sbPhishingToSbCat(mSbPhishing.get()); + | ContentBlocking.sbPhishingToSbCat(mSbPhishing.get()) + | ContentBlocking.sbHarmfulAddonToSbCat(mSbHarmfulAddon.get()); } /** @@ -1795,8 +1804,11 @@ public class ContentBlocking { /** Block phishing sites. */ public static final int PHISHING = 1 << 13; + /** Block harmful add-on sites. */ + public static final int HARMFULADDON = 1 << 14; + /** Block all unsafe sites. */ - public static final int DEFAULT = MALWARE | UNWANTED | HARMFUL | PHISHING; + public static final int DEFAULT = MALWARE | UNWANTED | HARMFUL | PHISHING | HARMFULADDON; /** Protected constructor for SafeBrowsing. */ protected SafeBrowsing() {} @@ -1809,7 +1821,8 @@ public class ContentBlocking { value = { SafeBrowsing.MALWARE, SafeBrowsing.UNWANTED, SafeBrowsing.HARMFUL, SafeBrowsing.PHISHING, - SafeBrowsing.DEFAULT, SafeBrowsing.NONE + SafeBrowsing.HARMFULADDON, SafeBrowsing.DEFAULT, + SafeBrowsing.NONE }) public @interface CBSafeBrowsing {} @@ -2031,6 +2044,7 @@ public class ContentBlocking { private static final String STP = "social-tracking-protection-facebook-digest256,social-tracking-protection-linkedin-digest256,social-tracking-protection-twitter-digest256"; private static final String EMAIL = "base-email-track-digest256"; + private static final String HARMFULADDON = "harmfuladdon-block-digest256"; /* package */ static @CBSafeBrowsing int sbMalwareToSbCat(final boolean enabled) { return enabled @@ -2042,6 +2056,10 @@ public class ContentBlocking { return enabled ? SafeBrowsing.PHISHING : SafeBrowsing.NONE; } + /* package */ static @CBSafeBrowsing int sbHarmfulAddonToSbCat(final boolean enabled) { + return enabled ? SafeBrowsing.HARMFULADDON : SafeBrowsing.NONE; + } + /* package */ static boolean catToSbMalware(@CBSafeBrowsing final int cat) { return (cat & (SafeBrowsing.MALWARE | SafeBrowsing.UNWANTED | SafeBrowsing.HARMFUL)) != 0; } @@ -2050,6 +2068,10 @@ public class ContentBlocking { return (cat & SafeBrowsing.PHISHING) != 0; } + /* package */ static boolean catToSbHarmfulAddon(@CBSafeBrowsing final int cat) { + return (cat & SafeBrowsing.HARMFULADDON) != 0; + } + /* package */ static String catToAtPref(@CBAntiTracking final int cat) { final StringBuilder builder = new StringBuilder(); @@ -2202,6 +2224,9 @@ public class ContentBlocking { if (error == 0x805D001EL) { return SafeBrowsing.MALWARE; } + if (error == 0x805D002E) { + return SafeBrowsing.HARMFULADDON; + } if (error == 0x805D0023L) { return SafeBrowsing.UNWANTED; } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebRequestError.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebRequestError.java @@ -60,6 +60,7 @@ public class WebRequestError extends Exception { ERROR_SAFEBROWSING_MALWARE_URI, ERROR_SAFEBROWSING_UNWANTED_URI, ERROR_SAFEBROWSING_HARMFUL_URI, + ERROR_HARMFULADDON_URI, ERROR_CONTENT_CRASHED, ERROR_OFFLINE, ERROR_PORT_BLOCKED, @@ -201,6 +202,9 @@ public class WebRequestError extends Exception { /** The requested URI was present in the "phishing" blocklist. */ public static final int ERROR_SAFEBROWSING_PHISHING_URI = 0x57; + /** The requested URI was present in the "harmful-addon" blocklist. */ + public static final int ERROR_HARMFULADDON_URI = 0x67; + /** The error code, e.g. {@link #ERROR_MALFORMED_URI}. */ public final int code; @@ -306,6 +310,9 @@ public class WebRequestError extends Exception { if (geckoError == XPCOMError.NS_ERROR_HARMFUL_URI) { return ERROR_SAFEBROWSING_HARMFUL_URI; } + if (geckoError == XPCOMError.NS_ERROR_HARMFULADDON_URI) { + return ERROR_HARMFULADDON_URI; + } // content if (geckoError == XPCOMError.NS_ERROR_CONTENT_CRASHED) { return ERROR_CONTENT_CRASHED; diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md @@ -13,6 +13,12 @@ exclude: true ⚠️ breaking change and deprecation notices +## v148 +- Introduce the harmful-addon URL-Classifier feature + - [`HARMFULADDON`][148.1] + +[148.1]: {{javadoc_uri}}/ContentBlocking.SafeBrowsing.html#HARMFULADDON + ## v147 - Changed Local Network / Device Access APIs in `GeckoRuntimeSettings` & `GeckoRuntimeSettings.Builder` for more granularity - Added new APIs in `GeckoRuntimeSettings` @@ -1877,4 +1883,4 @@ to allow adding gecko profiler markers. [65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String) [65.25]: {{javadoc_uri}}/GeckoResult.html -[api-version]: 1ec5960c50a5a9f6d11f0444d96ad04478fd9857 +[api-version]: 06cc6fd405532b3517d633ecee744d74223c6bc2 diff --git a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java @@ -2646,6 +2646,8 @@ public class GeckoViewActivity extends AppCompatActivity return "ERROR_SAFEBROWSING_UNWANTED_URI"; case WebRequestError.ERROR_SAFEBROWSING_HARMFUL_URI: return "ERROR_SAFEBROWSING_HARMFUL_URI"; + case WebRequestError.ERROR_HARMFULADDON_URI: + return "ERROR_HARMFULADDON_URI"; case WebRequestError.ERROR_CONTENT_CRASHED: return "ERROR_CONTENT_CRASHED"; case WebRequestError.ERROR_OFFLINE: diff --git a/mobile/shared/modules/geckoview/LoadURIDelegate.sys.mjs b/mobile/shared/modules/geckoview/LoadURIDelegate.sys.mjs @@ -90,7 +90,8 @@ export const LoadURIDelegate = { aError === Cr.NS_ERROR_PHISHING_URI || aError === Cr.NS_ERROR_MALWARE_URI || aError === Cr.NS_ERROR_HARMFUL_URI || - aError === Cr.NS_ERROR_UNWANTED_URI + aError === Cr.NS_ERROR_UNWANTED_URI || + aError === Cr.NS_ERROR_HARMFULADDON_URI ); }, };