-
encode_body: Security fix for:form_multipartheader injection
(GHSA-px9f-whj3-246m).The multipart encoder interpolated the per-part
name,filename, and
content_typeinto the part headers without escaping, so an
attacker-controlled value could inject extra headers or smuggle additional
parts into the request. These values are now escaped per RFC 7578 / WHATWG
form-data (", CR, and LF are percent-encoded).Thanks to @PJUllrich for reporting it.
-
decode_body: Drop automatic zip/tar/tgz/gz/zst/csv decoding,
(GHSA-655f-mp8p-96gv).Req previously auto-decoded archive and compressed response bodies (
zip,
tar,tgz,gz,zst, andcsv) based on the server-supplied
content-type, materialising the full decompressed contents in memory with
no size cap. An attacker-controlled (or redirect-reachable) endpoint could
return a tiny "decompression bomb" that expanded to gigabytes and exhausted
the node's memory.Now only JSON is decoded by default. Other formats are opt-in via the new
:decodersoption, which defaults to[:json, :json_api]. Setting it
replaces the default (include:jsonto keep JSON decoding), andfalse
disables all decoding:# opt into archives (only for endpoints you trust): Req.get!(url, decoders: [:json, :zip])Note: The decoded zip/tar is still list of
{filename :: charlist(), contents :: binary}tuples.
In the future release, this will be list of
{filename :: binary(), contents :: binary()}tuples.While automatic CSV decoding wasn't a security issue, the behaviour based
on presence/absence ofnimble_csvdependency was suprising. CSV support
is still built-in but need to be enabled withdecoders: [:csv].Custom decoders are supported via
{format, codec}tuples, wherecodecis
a module exportingdecode/1or a 1-arity function returning an:ok/:error
tuple, for example:Req.get!(url, decoders: [:json, ics: &{:ok, ICal.from_ics(&1)}])Thanks to @PJUllrich for reporting it.