The content-type sniffer had two memory/concurrency bugs. Number sniffing in isjson stored the strtod end-pointer out-parameter in a shared module-global Vector{Ptr{UInt8}}; concurrent sniff calls on a multithreaded server raced on that single cell between the ccall and the subsequent read, producing a non-deterministic consumed length and parse result an attacker could use to influence content-type classification. The bytes handed to jl_strtod_c were also not NUL-terminated, so strtod could read past the provided buffer. Separately, the MP4 ftyp matcher iterated comparison windows under @inbounds with a loop bound that, when boxsize == length(data), read up to three bytes past the end of the buffer.
On a multithreaded server, attacker-influenced input could non-deterministically affect content-type classification, and crafted buffers could trigger out-of-bounds heap reads (crash or potential information disclosure).
Fixed in HTTP.jl v2.4.0. The shared global is removed in favor of a per-call Ref; numeric input is copied into a freshly allocated NUL-terminated buffer so strtod is bounded; and the MP4 matcher's loop upper bound is clamped so every comparison window lies fully within the buffer.
Reported to the JuliaLang security team through Anthropic's Coordinated Vulnerability Disclosure program.
{
"license": "CC-BY-4.0"
}