Skip to content

build(deps): bump form-data from 3.0.4 to 3.0.5 - #2381

Merged
github-actions[bot] merged 1 commit into
masterfrom
dependabot/npm_and_yarn/form-data-3.0.5
Sep 21, 2026
Merged

github-actions[bot] merged 1 commit into
masterfrom
dependabot/npm_and_yarn/form-data-3.0.5

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jun 19, 2026 •

Copy link
Copy Markdown
Contributor

Bumps form-data from 3.0.4 to 3.0.5.

Changelog

Sourced from form-data's changelog.

v3.0.5 - 2026-06-12

Commits

  • [Fix] escape CR, LF, and " in field names and filenames 8777e67
  • [Dev Deps] update @ljharb/eslint-config, auto-changelog, eslint, tape 27c61a5
  • [Deps] update hasown 6a8a1c6
Commits
  • be3f3cf v3.0.5
  • 6a8a1c6 [Deps] update hasown
  • 27c61a5 [Dev Deps] update @ljharb/eslint-config, auto-changelog, eslint, tape
  • 8777e67 [Fix] escape CR, LF, and " in field names and filenames
  • See full diff in compare view

Note
Automatic rebases have been disabled on this pull request as it has been open for over 30 days.

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code labels Jun 19, 2026
@github-actions
github-actions Bot enabled auto-merge June 19, 2026 20:24
@martastn martastn self-assigned this Sep 20, 2026
@martastn

Copy link
Copy Markdown
Contributor

Review:

This bump is a security fix, not a routine bump. The commit touches only package-lock.json (7 lines); package.json is untouched, because form-data is not a direct dependency of this project at all.

Two lockfile entries move:

  • form-data 3.0.4 → 3.0.5
  • hasown 2.0.2 → 2.0.4 (pulled in automatically, because form-data's dependency range moved from ^2.0.2 to ^2.0.4)

The upstream fix is GHSA-hmw2-7cc7-3qxx (CWE-93, CRLF/header injection): a field name or filename containing \r, \n or " was concatenated verbatim into the Content-Disposition header, letting a caller that passes attacker-controlled names break out of the header line to inject headers or smuggle extra multipart parts. The fix escapes them as %0D, %0A, %22.

I diffed the published tarballs to get the complete change surface rather than trusting the changelog:

  • form-data 3.0.4 → 3.0.5 - the only runtime file changed is lib/form_data.js, with exactly three hunks: a new escapeHeaderParam() helper plus its two call sites (field name in _multiPartHeader, filename in _getContentDisposition). lib/browser.js and lib/populate.js are unchanged; everything else that differs is README.md/CHANGELOG.md/package.json.
  • hasown 2.0.2 → 2.0.4 - index.js and index.d.ts are byte-identical; only .eslintrc → eslint.config.mjs, the changelog and package.json differ. The two [types] commits in its history add and then drop the same overload, so they cancel out. A runtime no-op.

Where this project uses the library

Nowhere directly. grep for form-data/form_data across the repo (excluding node_modules, build and the lockfile) returns zero matches - no source file, script, config or CI workflow references it. It reaches the tree purely transitively, through the test toolchain:

react-scripts@5.0.1 → jest@27.5.1 → @jest/core → jest-config
  → jest-environment-jsdom@27.5.1 → jsdom@16.7.0 (nested) → form-data@3.0.5

There is exactly one consumer and one require site in the whole tree - jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:12 (require("form-data")) - reached only inside one guarded branch (~line 294), when an XMLHttpRequest body is a FormData instance:

if (flag.formData) {
  requestBody = new FormData();
  for (const entry of body) { requestBody.append(entry.name, entry.value, entry.options); }
  requestHeaders["Content-Type"] = `multipart/form-data; boundary=${requestBody.getBoundary()}`;
}

The hoisted jsdom@26.1.0 (via jsroot) does not depend on form-data at all - newer jsdom dropped it. The patched package is confined to the Jest 27 jsdom environment.

How the bump affects those usages - every path checked

# Possible path of impact Result
1 Direct import in src/ None - 0 occurrences anywhere in the repo's own code/config
2 App builds multipart bodies itself None - new FormData( has 0 occurrences in src/; the only XMLHttpRequest usage is the Emscripten WASM loader stub (geant-web-stubs/geant4_wasm.js) doing xhr.send(null), i.e. no body
3 Production bundle Full react-app-rewired build (exit 0), then grepped the output: form_data and getBoundary - the package's own code signatures - have 0 hits. Not shipped to users. (See the note below.)
4 Test runtime (the only place it can execute) Requires an XHR with a FormData body; no test references FormData or XMLHttpRequest, so it never runs. On 3.0.5: 8/8 jsdom unit suites pass. The 5 failing suites are Selenium E2E ones failing with net::ERR_CONNECTION_REFUSED (no dev server running locally); no error mentions form-data/FormData/jsdom
5 Duplicate / conflicting installs Single lockfile entry, single physical node_modules/form-data - no version split
6 Fallout from the hasown bump (18 dependents) All declare ^2.0.1/^2.0.2, all satisfied by 2.0.4; single hoisted instance; runtime byte-identical as shown above
7 Node/engines compatibility engines: { node: ">= 6" } identical in both versions; CI runs Node 24.x
8 overrides/resolutions interference package.json only overrides typescript - nothing pins or conflicts
9 Custom webpack config config-overrides.js has no alias, fallback or IgnorePlugin rule touching form-data
10 Hypothetical browser bundling Webpack would substitute the package's browser field (lib/browser.js), which is byte-identical between the versions
11 Behavioral change if it did run Escaping only alters names containing \r, \n or "; upstream tests assert ordinary names stay verbatim (name="items[0]"). No visual or functional change for normal inputs

Note on a misleading grep hit: the production bundle does contain the literal string form-data (2 hits in main.js), but it is not this package - it is ky: ky/distribution/core/constants.js (formData: 'multipart/form-data' in its accept-header map) and ky/distribution/utils/body.js, whose getBodySize() builds a Content-Disposition: form-data; name="${key}" string purely to estimate upload size for progress reporting. That is ky's own code, never touching the form-data package, and the app never passes a FormData body to ky anyway (see row 2).

Conclusion

Legitimate upstream security patch with a minimal, fully-reviewed diff. In this repo the vulnerable code has no reachable execution path: the package lives only inside Jest's jsdom environment, is never bundled for production, and nothing in the codebase constructs a FormData - let alone one with attacker-controlled field names or filenames. The hasown bump is a runtime no-op.

Nothing to verify visually, nothing that can regress. Confirmed safe to merge.

@martastn

Copy link
Copy Markdown
Contributor

@dependabot rebase

Bumps [form-data](https://github.com/form-data/form-data) from 3.0.4 to 3.0.5.
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](form-data/form-data@v3.0.4...v3.0.5)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 3.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot
dependabot Bot force-pushed the dependabot/npm_and_yarn/form-data-3.0.5 branch from 46258ed to b1db72d Compare September 21, 2026 15:56
@github-actions
github-actions Bot added this pull request to the merge queue Sep 21, 2026
Merged via the queue into master with commit afd632b Sep 21, 2026
7 checks passed
@github-actions
github-actions Bot deleted the dependabot/npm_and_yarn/form-data-3.0.5 branch September 21, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant