Skip to content

fix(deps): update dependency form-data to ^4.0.6 [security]#17

Open
renovate-ce-paramount-engineering[bot] wants to merge 1 commit into
mainfrom
renovate/npm-form-data-vulnerability
Open

fix(deps): update dependency form-data to ^4.0.6 [security]#17
renovate-ce-paramount-engineering[bot] wants to merge 1 commit into
mainfrom
renovate/npm-form-data-vulnerability

Conversation

@renovate-ce-paramount-engineering

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
form-data ^4.0.0^4.0.6 age confidence

form-data: CRLF injection in form-data via unescaped multipart field names and filenames

CVE-2026-12143 / GHSA-hmw2-7cc7-3qxx

More information

Details

Summary

form-data builds multipart/form-data request bodies. Through v4.0.5, the field name passed to FormData#append and the filename option are concatenated directly into the Content-Disposition header with no escaping of CR (\r), LF (\n), or ". An application that uses untrusted input as a field name or filename therefore lets an attacker terminate the header line and either inject additional headers or smuggle whole additional multipart parts into the request the application forwards to a backend.

This is CWE-93 (CRLF injection). It is a divergence from how browsers and the WHATWG HTML spec serialize form-data (they escape these characters), so the fix is to match that behavior. Severity is conditional: it depends on the consuming application passing attacker-controlled data as a field name or filename. Applications that only use fixed/trusted field names are not affected.

Details

In lib/form_data.js, _multiPartHeader builds the part header as:

'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || [])

and _getContentDisposition builds filename="' + filename + '"'. Neither escapes control characters, so a \r\n in field/filename ends the header line. The same applies to ", which can break out of the quoted parameter.

Proof of concept
const FormData = require('form-data');
const form = new FormData();
form.append('email"\r\nX-Injected: true\r\nfake="', 'user@example.com');
console.log(form.getBuffer().toString());

Before the fix this emits an injected X-Injected: true header line. A field name that also includes --<boundary> sequences can introduce additional parts (e.g. an extra name="is_admin" field), which a downstream parser accepts as legitimate.

Impact

For an application that uses untrusted field names/filenames:

  • Field injection / override (integrity). Inject or override fields the backend trusts (e.g. is_admin, role) — the primary demonstrated impact.
  • Header injection into the generated multipart part.

Claims of guaranteed privilege escalation, authentication bypass, high confidentiality impact, and availability impact are application-dependent downstream consequences, not properties of form-data itself, and are not demonstrated by the PoC.

Severity

The demonstrated, library-attributable impact is integrity (field/header injection); there is no demonstrated confidentiality disclosure or availability impact in form-data itself, and exploitation requires the consuming app to feed untrusted data into field names/filenames. A Moderate (≈5.3, I:L) rating is also defensible given that precondition.

Patch

Fixed in 4.0.6, 3.0.5, and 2.5.6. Users on older 0.x/1.x/2.x releases should upgrade to 2.5.6 or later.

The fix escapes \r, \n, and " as %0D, %0A, and %22 in field names and filenames, matching the WHATWG HTML multipart/form-data encoding algorithm that browsers implement. This neutralizes the injection while leaving ordinary field names (including name[0], dotted, and unicode names) unchanged.

Workaround

Until upgrading, validate or reject field names/filenames that contain control characters before calling append:

if (/[\r\n]/.test(field)) { throw new Error('invalid field name'); }
Credit

Reported by yueyueL.

Severity

  • CVSS Score: 8.7 / 10 (High)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

form-data/form-data (form-data)

v4.0.6

Compare Source

Commits
  • [Fix] escape CR, LF, and " in field names and filenames 8dff42c
  • [Dev Deps] update @ljharb/eslint-config, auto-changelog, tape f31d21e
  • [Deps] update hasown, mime-types 92ae0eb
  • [Dev Deps] update js-randomness-predictor 67b0f65

v4.0.5

Compare Source

Commits
  • [Tests] Switch to newer v8 prediction library; enable node 24 testing 16e0076
  • [Dev Deps] update @ljharb/eslint-config, eslint 5822467
  • [Fix] set Symbol.toStringTag in the proper place 76d0dee

v4.0.4

Compare Source

Commits
  • [meta] add auto-changelog 811f682
  • [Tests] handle predict-v8-randomness failures in node < 17 and node > 23 1d11a76
  • [Fix] Switch to using crypto random for boundary values 3d17230
  • [Tests] fix linting errors 5e34080
  • [meta] actually ensure the readme backup isn’t published 316c82b
  • [Dev Deps] update @ljharb/eslint-config 58c25d7
  • [meta] fix readme capitalization 2300ca1

v4.0.3

Compare Source

Fixed
  • [Fix] append: avoid a crash on nullish values #577
Commits
  • [eslint] use a shared config 426ba9a
  • [eslint] fix some spacing issues 2094191
  • [Refactor] use hasown 81ab41b
  • [Fix] validate boundary type in setBoundary() method 8d8e469
  • [Tests] add tests to check the behavior of getBoundary with non-strings 837b8a1
  • [Dev Deps] remove unused deps 870e4e6
  • [meta] remove local commit hooks e6e83cc
  • [Dev Deps] update eslint 4066fd6
  • [meta] fix scripts to use prepublishOnly c4bbb13

v4.0.2

Compare Source

Merged
  • [Fix] set Symbol.toStringTag when available #573
  • [Fix] set Symbol.toStringTag when available #573
  • fix (npmignore): ignore temporary build files #532
  • fix (npmignore): ignore temporary build files #532
Fixed
  • [Fix] set Symbol.toStringTag when available (#​573) #396
  • [Fix] set Symbol.toStringTag when available (#​573) #396
  • [Fix] set Symbol.toStringTag when available #396
Commits
  • Merge tags v2.5.3 and v3.0.3 92613b9
  • [Tests] migrate from travis to GHA 806eda7
  • [Tests] migrate from travis to GHA 8fdb3bc
  • [Refactor] use Object.prototype.hasOwnProperty.call 7fecefe
  • [Refactor] use Object.prototype.hasOwnProperty.call 6e682d4
  • [Refactor] use Object.prototype.hasOwnProperty.call df3c1e6
  • [Dev Deps] update @types/node, browserify, coveralls, cross-spawn, eslint, formidable, in-publish, pkgfiles, pre-commit, puppeteer, request, tape, typescript 8261fcb
  • [Dev Deps] update @types/node, browserify, coveralls, cross-spawn, eslint, formidable, in-publish, pkgfiles, pre-commit, puppeteer, request, tape, typescript fb66cb7
  • [Dev Deps] update @types/node, browserify, coveralls, eslint, formidable, in-publish, phantomjs-prebuilt, pkgfiles, pre-commit, request, tape, typescript 819f6b7
  • [eslint] clean up ignores 3217b3d
  • [eslint] clean up ignores 3a9d480
  • [Fix] Buffer.from and Buffer.alloc require node 4+ c499f76
  • Only apps should have lockfiles b82f590
  • Only apps should have lockfiles b170ee2
  • [Deps] update combined-stream, mime-types 6b1ca1d
  • [Dev Deps] pin request which via tough-cookie ^2.4 depends on psl e5df7f2
  • [Deps] update mime-types 5a5bafe
  • Bumped version 2.5.3 9457283
  • [Dev Deps] pin request which via tough-cookie ^2.4 depends on psl 9dbe192
  • Merge tags v2.5.2 and v3.0.2 d53265d
  • Bumped version 2.5.2 7020dd4
  • [Dev Deps] downgrade cross-spawn 3fc1a9b
  • fix: move util.isArray to Array.isArray (#​564) edb555a
  • fix: move util.isArray to Array.isArray (#​564) 10418d1

v4.0.1

Compare Source

Commits
  • [Tests] migrate from travis to GHA 757b4e3
  • [eslint] clean up ignores e8f0d80
  • fix (npmignore): ignore temporary build files 335ad19
  • fix: move util.isArray to Array.isArray 440d3be

Configuration

📅 Schedule: (in timezone America/Los_Angeles)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate CE.

@renovate-ce-paramount-engineering renovate-ce-paramount-engineering Bot force-pushed the renovate/npm-form-data-vulnerability branch from 77acd20 to 42ceaac Compare June 23, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

0 participants