GHSA-px9f-whj3-246m

Suggest an improvement
Source
https://github.com/advisories/GHSA-px9f-whj3-246m
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-px9f-whj3-246m/GHSA-px9f-whj3-246m.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-px9f-whj3-246m
Aliases
Published
2026-07-29T15:29:14Z
Modified
2026-07-29T15:52:24Z
Severity
  • 6.3 (Medium) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N CVSS Calculator
Summary
Req vulnerable to multipart form-data header injection via unescaped name/filename/content_type
Details

Summary

Req's multipart form encoder interpolates the per-part name, filename, and content_type directly into the part headers without escaping. An attacker who can influence any of those values can inject CRLF-separated header lines, smuggle additional form fields, or prepend a whole extra part into the request the victim service sends downstream.

Details

Req.Utils.encode_form_part/2 in lib/req/utils.ex builds the per-part header iodata by concatenating the three caller-supplied strings verbatim into content-disposition: form-data; name="<name>"; filename="<filename>" and content-type: <content_type>. There is no CRLF stripping, no quote escaping, and no validation. A value containing "\r\n closes the surrounding quoted value and starts a new header line; an additional \r\n--<boundary> terminates the current part and lets the attacker prepend a smuggled part.

The flaw is reachable through every supported way of supplying a part. It is especially easy to hit when value is a %File.Stream{}, because filename then defaults to Path.basename(stream.path) and POSIX filenames may legitimately contain \r and \n. RFC 7578 / WHATWG form-data requires percent-encoding ", CR, and LF in these fields; the fix adopts that behavior.

PoC

  1. Construct a malicious filename such as harmless.txt"\r\nX-Smuggled: marker\r\nContent-Disposition: form-data; name="pwned.
  2. Call Req.post!(url, form_multipart: [upload: {"benign body", filename: <malicious>, content_type: "text/plain"}]).
  3. The emitted multipart body contains a real X-Smuggled: header line and an extra Content-Disposition for name="pwned", alongside Req's legitimate headers.

Impact

HTTP request smuggling / multipart parameter smuggling in the HTTP client. Any application using Req to send form_multipart requests where any of name, filename, or content_type can be influenced by an untrusted source is affected, most commonly upload proxies and re-uploaders that derive filename from Path.basename/1 on a user-controlled path.

Database specific
{
    "cwe_ids":  [
        "CWE-93"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-07-29T15:29:14Z",
    "nvd_published_at":  "2026-06-08T16:16:44Z",
    "severity":  "MODERATE"
}
References

Affected packages

Hex / req

Package

Name
req
Purl
pkg:hex/req

Affected ranges

Type
SEMVER
Events
Introduced
0.5.3
Fixed
0.6.0

Affected versions

0.*
0.5.3
0.5.4
0.5.5
0.5.6
0.5.7
0.5.8
0.5.9
0.5.10
0.5.11
0.5.12
0.5.13
0.5.14
0.5.15
0.5.16
0.5.17
0.5.18

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-px9f-whj3-246m/GHSA-px9f-whj3-246m.json"