Low CVSS 7.7 firefox Input Validation 🔧 Commit mapped

Overview

Low
Severity
7.7
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactlow
DescriptionAfter selecting a malicious Windows <code>.url</code> shortcut from the local filesystem, an unexpected file could be uploaded. <br>*This bug only affects Firefox on Windows. Other operating systems are unaffected.*
ComponentWidget
Bug ClassInput Validation
Tracker1950056
Fix commit0bdb9dd88c50 (firefox) +25/-6
CWECWE-73
CVSS vectorCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
CISA KEVNot listed
CreditedAmeen Basha M K
Disclosed2025-04-01

Background

`nsFilePicker::ShowFilePicker`
The Windows implementation (widget/windows/nsFilePicker.cpp) that configures and shows the native Common Item Dialog used for file open/save, including HTML <input type=file> uploads.
`FILEOPENDIALOGOPTIONS` (`fos`)
The option bitmask passed to the Windows dialog. FOS_FILEMUSTEXIST, FOS_ALLOWMULTISELECT, and FOS_NODEREFERENCELINKS control existence checks, multi-select, and whether the dialog resolves (dereferences) shell links/shortcuts.
`FOS_NODEREFERENCELINKS`
When set, the dialog returns the path of the selected .lnk/.url shortcut itself rather than following it to its target. When cleared, the dialog silently resolves the shortcut to its target path.
`widget.windows.follow_shortcuts_on_file_open`
A new static pref (RelaxedAtomicInt32, default 2/“auto”) introduced by the patch to control shortcut dereferencing in the open dialog (0=never, 1=always, 2=auto).

Root Cause Analysis

In the open modes, the old code set only FOS_FILEMUSTEXIST and left FOS_NODEREFERENCELINKS unset, so the native dialog would dereference a shortcut the user selected: picking a .url (or .lnk) returned the shortcut’s target path, not the shortcut file. For a web-initiated upload (<input type=file>), that means selecting a crafted shortcut could cause Firefox to read and upload a file the shortcut points to, which may differ from the file the user believes they chose — an attacker-controlled redirection of the uploaded path. The code already understood this hazard for the save path (the pre-existing FOS_NODEREFERENCELINKS guard plus the bug-271732 comment about not following shortcuts when saving), but the open path had no equivalent protection.

The patch reorders the switch (mMode) so modeOpenMultiple falls through into modeOpen, and for the open case consults the new widget_windows_follow_shortcuts_on_file_open() pref: for every value except 1 (“always”) it adds fos |= FOS_NODEREFERENCELINKS, so by default (value 2) the dialog no longer dereferences shortcuts and returns the shortcut file itself. The save path’s comment is updated to reference bug 283730. This is a logic/input-validation fix: the dialog was configured to trust shortcut dereferencing on the untrusted open/upload path.

Key insight
The Windows open/upload dialog was left to silently follow .url/.lnk shortcuts, so a user selecting a malicious shortcut uploaded the shortcut’s target file instead of the file they picked; the fix sets FOS_NODEREFERENCELINKS by default on open.

Attack Path

  1. Lure A web page presents a file upload and social-engineers the user into selecting a specific file from the local filesystem (inferred web reachability via <input type=file>; the diff shows the picker but not the caller).
  2. Malicious shortcut The attacker has placed (or convinced the user to navigate to) a crafted Windows .url/.lnk whose target is a sensitive file the attacker wants exfiltrated.
  3. Selection The user picks the shortcut in the open dialog, believing they are uploading the shortcut/benign file.
  4. Silent dereference Because FOS_NODEREFERENCELINKS is unset, the dialog resolves the shortcut and hands Firefox the target path instead.
  5. Primitive Firefox reads and uploads the unexpected target file, disclosing its contents to the attacker’s site (Windows-only).

Impact Assessment

Renderer-initiated but executed in the parent/widget code; no elevated privilege is needed beyond the user operating a file-upload dialog. The gained primitive is reading and uploading a file the user did not knowingly choose (confidentiality/integrity of local files, CVSS 7.7 local vector), gated on user interaction with the dialog, on the attacker controlling or planting a shortcut, and on the platform being Windows (other OSes unaffected). It is not memory corruption or code execution.

Changed Functions

FunctionChangeNotes
switch
widget/windows/nsFilePicker.cpp
modified

Files Changed

  • modules/libpref/init/StaticPrefList.yaml
  • widget/windows/nsFilePicker.cpp

Audit Directions

  • Other picker modes/entry points
    Review modeSave/IsDefaultPathLink handling and any other place that constructs FILEOPENDIALOGOPTIONS to confirm shortcut dereferencing matches the trust level of the operation.
  • Path returned vs. path uploaded
    Audit the upload/nsIFilePicker consumers to ensure they use the returned path as-is and do not perform additional shortcut resolution.
  • Cross-platform shortcut handling
    Check macOS/Linux file pickers and alias/symlink resolution for analogous “silently follow link on open” behavior.
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
index f53097af43d..61e90f1fb7d 100644
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -18407,6 +18407,17 @@
   value: 0
   mirror: always
 
+# Whether to follow `.lnk` (etc.) shortcuts in the Windows file-open dialog.
+#
+# Valid values:
+#  * 0: never
+#  * 1: always
+#  * 2: auto
+- name: widget.windows.follow_shortcuts_on_file_open
+  type: RelaxedAtomicInt32
+  value: 2
+  mirror: always
+
 # The number of messages of each type to keep for display in
 # about:windows-messages
 - name: widget.windows.messages_to_log
diff --git a/widget/windows/nsFilePicker.cpp b/widget/windows/nsFilePicker.cpp
index 08d86081c76..a21f914eba6 100644
--- a/widget/windows/nsFilePicker.cpp
+++ b/widget/windows/nsFilePicker.cpp
@@ -552,18 +552,26 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) {
 
     // mode specification
     switch (mMode) {
+      case modeOpenMultiple:
+        fos |= FOS_ALLOWMULTISELECT;
+        [[fallthrough]];
+
       case modeOpen:
         fos |= FOS_FILEMUSTEXIST;
-        break;
-
-      case modeOpenMultiple:
-        fos |= FOS_FILEMUSTEXIST | FOS_ALLOWMULTISELECT;
+        switch (mozilla::StaticPrefs::
+                    widget_windows_follow_shortcuts_on_file_open()) {
+          case 1:
+            break;
+          default:
+            fos |= FOS_NODEREFERENCELINKS;
+        }
         break;
 
       case modeSave:
         fos |= FOS_NOREADONLYRETURN;
-        // Don't follow shortcuts when saving a shortcut, this can be used
-        // to trick users (bug 271732)
+        // Don't follow shortcuts when saving a shortcut; this can be used to
+        // trick users (bug 271732). _Do_ follow shortcuts when not saving a
+        // shortcut (bug 283730).
         if (IsDefaultPathLink()) {
           fos |= FOS_NODEREFERENCELINKS;
         }
Loading diff…