ma1 pushed to branch tor-browser-102.12.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
38cb023e
by hackademix at 2023-06-28T08:12:58+02:00
-
d3b18f88
by hackademix at 2023-06-28T08:16:35+02:00
5 changed files:
- browser/app/profile/001-base-profile.js
- browser/components/downloads/DownloadSpamProtection.jsm
- toolkit/components/downloads/DownloadCore.jsm
- toolkit/components/downloads/DownloadIntegration.jsm
- uriloader/exthandler/nsExternalHelperAppService.cpp
Changes:
... | ... | @@ -48,6 +48,9 @@ pref("security.nocertdb", true); |
48 | 48 | pref("browser.download.useDownloadDir", false);
|
49 | 49 | pref("browser.download.manager.addToRecentDocs", false);
|
50 | 50 | |
51 | +// Prevent download stuffing / DOS (tor-browser#41764)
|
|
52 | +pref("browser.download.enable_spam_prevention", true);
|
|
53 | + |
|
51 | 54 | // Misc privacy: Disk
|
52 | 55 | pref("signon.rememberSignons", false);
|
53 | 56 | pref("browser.formfill.enable", false);
|
... | ... | @@ -18,6 +18,8 @@ var { XPCOMUtils } = ChromeUtils.import( |
18 | 18 | "resource://gre/modules/XPCOMUtils.jsm"
|
19 | 19 | );
|
20 | 20 | |
21 | +var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
22 | + |
|
21 | 23 | XPCOMUtils.defineLazyModuleGetters(this, {
|
22 | 24 | BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
|
23 | 25 | Downloads: "resource://gre/modules/Downloads.jsm",
|
... | ... | @@ -45,17 +47,18 @@ class DownloadSpamProtection { |
45 | 47 | return this.list;
|
46 | 48 | }
|
47 | 49 | |
48 | - update(url) {
|
|
50 | + update(url, principal) {
|
|
49 | 51 | if (this._blockedURLToDownloadSpam.has(url)) {
|
50 | 52 | let downloadSpam = this._blockedURLToDownloadSpam.get(url);
|
51 | 53 | this.spamList.remove(downloadSpam);
|
54 | + downloadSpam.principal = principal;
|
|
52 | 55 | downloadSpam.blockedDownloadsCount += 1;
|
53 | 56 | this.spamList.add(downloadSpam);
|
54 | 57 | this._indicator.onDownloadStateChanged(downloadSpam);
|
55 | 58 | return;
|
56 | 59 | }
|
57 | 60 | |
58 | - let downloadSpam = new DownloadSpam(url);
|
|
61 | + let downloadSpam = new DownloadSpam(url, principal, this);
|
|
59 | 62 | this.spamList.add(downloadSpam);
|
60 | 63 | this._blockedURLToDownloadSpam.set(url, downloadSpam);
|
61 | 64 | let hasActiveDownloads = DownloadsCommon.summarizeDownloads(
|
... | ... | @@ -85,8 +88,10 @@ class DownloadSpamProtection { |
85 | 88 | * @extends Download
|
86 | 89 | */
|
87 | 90 | class DownloadSpam extends Download {
|
88 | - constructor(url) {
|
|
91 | + constructor(url, principal, protectionController) {
|
|
89 | 92 | super();
|
93 | + this.protectionController = protectionController;
|
|
94 | + this.principal = principal.QueryInterface(Ci.nsIPrincipal);
|
|
90 | 95 | this.hasBlockedData = true;
|
91 | 96 | this.stopped = true;
|
92 | 97 | this.error = new DownloadError({
|
... | ... | @@ -97,4 +102,16 @@ class DownloadSpam extends Download { |
97 | 102 | this.source = { url };
|
98 | 103 | this.blockedDownloadsCount = 1;
|
99 | 104 | }
|
105 | + allow() {
|
|
106 | + const pm = Services.perms;
|
|
107 | + pm.addFromPrincipal(
|
|
108 | + this.principal,
|
|
109 | + "automatic-download",
|
|
110 | + pm.ALLOW_ACTION,
|
|
111 | + pm.EXPIRE_SESSION
|
|
112 | + );
|
|
113 | + this.hasBlockedData = this.hasPartialData = false;
|
|
114 | + this.protectionController.clearDownloadSpam(this.source.url);
|
|
115 | + this._notifyChange();
|
|
116 | + }
|
|
100 | 117 | } |
... | ... | @@ -717,6 +717,10 @@ Download.prototype = { |
717 | 717 | }
|
718 | 718 | |
719 | 719 | this._promiseUnblock = (async () => {
|
720 | + if (this.allow) {
|
|
721 | + this.allow();
|
|
722 | + return;
|
|
723 | + }
|
|
720 | 724 | try {
|
721 | 725 | await IOUtils.move(this.target.partFilePath, this.target.path);
|
722 | 726 | await this.target.refresh();
|
... | ... | @@ -725,7 +729,6 @@ Download.prototype = { |
725 | 729 | this._promiseUnblock = null;
|
726 | 730 | throw ex;
|
727 | 731 | }
|
728 | - |
|
729 | 732 | this.succeeded = true;
|
730 | 733 | this.hasBlockedData = false;
|
731 | 734 | this._notifyChange();
|
... | ... | @@ -955,7 +958,9 @@ Download.prototype = { |
955 | 958 | await this._promiseCanceled;
|
956 | 959 | }
|
957 | 960 | // Ask the saver object to remove any partial data.
|
958 | - await this.saver.removeData();
|
|
961 | + if (this.saver) {
|
|
962 | + await this.saver.removeData();
|
|
963 | + }
|
|
959 | 964 | // For completeness, clear the number of bytes transferred.
|
960 | 965 | if (this.currentBytes != 0 || this.hasPartialData) {
|
961 | 966 | this.currentBytes = 0;
|
... | ... | @@ -1234,7 +1234,7 @@ var DownloadObserver = { |
1234 | 1234 | ) {
|
1235 | 1235 | DownloadIntegration._initializeDownloadSpamProtection();
|
1236 | 1236 | }
|
1237 | - DownloadIntegration.downloadSpamProtection.update(aData);
|
|
1237 | + DownloadIntegration.downloadSpamProtection.update(aData, aSubject);
|
|
1238 | 1238 | break;
|
1239 | 1239 | }
|
1240 | 1240 | },
|
... | ... | @@ -1975,7 +1975,7 @@ bool nsExternalAppHandler::IsDownloadSpam(nsIChannel* aChannel) { |
1975 | 1975 | nsAutoCString cStringURI;
|
1976 | 1976 | loadInfo->TriggeringPrincipal()->GetPrePath(cStringURI);
|
1977 | 1977 | observerService->NotifyObservers(
|
1978 | - nullptr, "blocked-automatic-download",
|
|
1978 | + principal, "blocked-automatic-download",
|
|
1979 | 1979 | NS_ConvertASCIItoUTF16(cStringURI.get()).get());
|
1980 | 1980 | // FIXME: In order to escape memory leaks, currently we cancel blocked
|
1981 | 1981 | // downloads. This is temporary solution, because download data should be
|
... | ... | @@ -1989,7 +1989,7 @@ bool nsExternalAppHandler::IsDownloadSpam(nsIChannel* aChannel) { |
1989 | 1989 | if (!loadInfo->GetHasValidUserGestureActivation()) {
|
1990 | 1990 | permissionManager->AddFromPrincipal(
|
1991 | 1991 | principal, type, nsIPermissionManager::PROMPT_ACTION,
|
1992 | - nsIPermissionManager::EXPIRE_NEVER, 0 /* expire time */);
|
|
1992 | + nsIPermissionManager::EXPIRE_SESSION, 0 /* expire time */);
|
|
1993 | 1993 | }
|
1994 | 1994 | |
1995 | 1995 | return false;
|