atis.http.* reads the entire HTTP response body into memory with no size limit and no default timeout #200
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
httpReq(the shared implementation behindatis.http.get/post/put/patch/delete) reads the whole response body viabody, err := io.ReadAll(resp.Body)with no upper bound whatsoever. Thehttp.Clientused for these calls ishttp.DefaultClient(assigned directly inNewAtisRuntime), whoseTimeoutis the zero value (no timeout) unless a script explicitly callsatis.http.set_timeout(...)beforehand. There is no equivalent here of the size/count guard rails the project already added elsewhere for archive extraction (atis.misc.unzip_targz'smaxCount/maxSizeparameters).Location
internal/atis/http.go, functionhttpReq, thebody, err := io.ReadAll(resp.Body)call (~line 155)internal/atis/atis.go, client construction:httpClient: http.DefaultClient(~line 53)Risk
Any script that calls
atis.http.get/post/etc. against an untrusted, misbehaving, or compromised endpoint — or simply one that returns an unexpectedly large response — will have the entire response body buffered into process memory in one call, with no cap. This is a straightforward memory-exhaustion vector (up to an OOM kill of the process/host) for any automation that fetches a URL influenced by external input, e.g. a webhook payload, a value read from a config/manifest file, or a redirect/response from a third-party API. Because the client has no default timeout either, a slow or stalled peer can also hang the call indefinitely, tying up an automation run with no bound. This is the same general class of "unbounded resource consumption from untrusted input" that the project already treated as worth a dedicated fix for archive extraction, but the HTTP path has no equivalent protection today.Advice for fix
Wrap
resp.Bodyin a bounded reader (e.g.io.LimitReaderor anhttp.MaxBytesReader-style approach) with a sane default maximum response size, ideally exposed as a configurable parameter similar tounzip_targz'smaxSize. Also set a sensible defaultTimeouton the HTTP client at construction time instead of leaving it at Go's zero value ("no timeout") until a script opts in viaset_timeout.