Skip to content

Commit 574bf71

Browse files
committed
Bug 1338637 - Ask user for confirmation before folder upload. r=Gijs,geckoview-reviewers,agi,baku
Differential Revision: https://phabricator.services.mozilla.com/D95324
1 parent 997b81e commit 574bf71

File tree

5 files changed

+96
-0
lines changed

5 files changed

+96
-0
lines changed

browser/components/prompts/PromptCollection.jsm

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,48 @@ class PromptCollection {
131131
result.QueryInterface(Ci.nsIPropertyBag2).get("buttonNumClicked") == 0
132132
);
133133
}
134+
135+
confirmFolderUpload(browsingContext, directoryName) {
136+
let title;
137+
let message;
138+
let acceptLabel;
139+
140+
try {
141+
title = this.stringBundles.dom.GetStringFromName(
142+
"FolderUploadPrompt.title"
143+
);
144+
message = this.stringBundles.dom.formatStringFromName(
145+
"FolderUploadPrompt.message",
146+
[directoryName]
147+
);
148+
acceptLabel = this.stringBundles.dom.GetStringFromName(
149+
"FolderUploadPrompt.acceptButtonLabel"
150+
);
151+
} catch (exception) {
152+
Cu.reportError("Failed to get strings from dom.properties");
153+
return false;
154+
}
155+
156+
let buttonFlags =
157+
Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
158+
Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
159+
Services.prompt.BUTTON_POS_1_DEFAULT;
160+
161+
return (
162+
Services.prompt.confirmExBC(
163+
browsingContext,
164+
Services.prompt.MODAL_TYPE_TAB,
165+
title,
166+
message,
167+
buttonFlags,
168+
acceptLabel,
169+
null,
170+
null,
171+
null,
172+
{}
173+
) === 0
174+
);
175+
}
134176
}
135177

136178
const BUNDLES = {

dom/html/HTMLInputElement.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "nsError.h"
5555
#include "nsIEditor.h"
5656
#include "nsAttrValueOrString.h"
57+
#include "nsIPromptCollection.h"
5758

5859
#include "mozilla/PresState.h"
5960
#include "nsLinebreakConverter.h" //to strip out carriage returns
@@ -480,6 +481,37 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult) {
480481
mode == static_cast<int16_t>(nsIFilePicker::modeGetFolder));
481482
nsCOMPtr<nsISupports> tmp;
482483
nsresult rv = mFilePicker->GetDomFileOrDirectory(getter_AddRefs(tmp));
484+
485+
// Show a prompt to get user confirmation before allowing folder access.
486+
// This is to prevent sites from tricking the user into uploading files.
487+
// See Bug 1338637.
488+
if (mode == static_cast<int16_t>(nsIFilePicker::modeGetFolder)) {
489+
nsCOMPtr<nsIPromptCollection> prompter =
490+
do_GetService("@mozilla.org/embedcomp/prompt-collection;1");
491+
if (!prompter) {
492+
return NS_ERROR_NOT_AVAILABLE;
493+
}
494+
495+
bool confirmed = false;
496+
BrowsingContext* bc = mInput->OwnerDoc()->GetBrowsingContext();
497+
498+
// Get directory name
499+
RefPtr<Directory> directory = static_cast<Directory*>(tmp.get());
500+
nsAutoString directoryName;
501+
ErrorResult error;
502+
directory->GetName(directoryName, error);
503+
if (NS_WARN_IF(error.Failed())) {
504+
return error.StealNSResult();
505+
}
506+
507+
rv = prompter->ConfirmFolderUpload(bc, directoryName, &confirmed);
508+
NS_ENSURE_SUCCESS(rv, rv);
509+
if (!confirmed) {
510+
// User aborted upload
511+
return NS_OK;
512+
}
513+
}
514+
483515
NS_ENSURE_SUCCESS(rv, rv);
484516

485517
RefPtr<Blob> blob = do_QueryObject(tmp);

dom/locales/en-US/chrome/dom/dom.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,7 @@ RequestStorageAccessNested=document.requestStorageAccess() may not be called in
401401
RequestStorageAccessUserGesture=document.requestStorageAccess() may only be requested from inside a short running user-generated event handler.
402402
# LOCALIZATION NOTE: Do not translate "Location" and "History".
403403
LocChangeFloodingPrevented=Too many calls to Location or History APIs within a short timeframe.
404+
FolderUploadPrompt.title = Confirm Upload
405+
# LOCALIZATION NOTE: %S is the name of the folder the user selected in the file picker.
406+
FolderUploadPrompt.message = Are you sure you want to upload all files from “%S”? Only do this if you trust the site.
407+
FolderUploadPrompt.acceptButtonLabel = Upload

mobile/android/components/geckoview/PromptCollection.jsm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class PromptCollection {
3838
prompter.asyncShowPrompt(msg, resolve);
3939
}).then(result => !!result?.allow);
4040
}
41+
42+
confirmFolderUpload() {
43+
// Folder upload is not supported by GeckoView yet, see Bug 1674428.
44+
return false;
45+
}
4146
}
4247

4348
PromptCollection.prototype.QueryInterface = ChromeUtils.generateQI([

toolkit/components/windowwatcher/nsIPromptCollection.idl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,17 @@ interface nsIPromptCollection : nsISupports
3333
* @return true if the page should be allowed to repost data.
3434
*/
3535
boolean confirmRepost(in BrowsingContext aBrowsingContext);
36+
37+
/**
38+
* Ask the user for confirmation to upload a selected folder.
39+
*
40+
* @param aBrowsingContext
41+
* The browsing context the prompt should be opened for.
42+
* @param aDirectoryName
43+
* Name of the folder that will be uploaded.
44+
*
45+
* @return true if the user confirmed the upload, false otherwise.
46+
*/
47+
boolean confirmFolderUpload(in BrowsingContext aBrowsingContext,
48+
in AString aDirectoryName);
3649
};

0 commit comments

Comments
 (0)