Max-Age integer wrap can alter cookie lifetime
low swesweep-fasthttp · cookie.go · Cookie.ParseBytes · run #4
Description
Max-Age is parsed into an int via ParseUint with no visible overflow guard. A crafted very large Max-Age value can wrap to zero or negative, causing the cookie to be treated as having no Max-Age or as immediately deleted, potentially altering client-side cookie lifetime.
Triage
Not triaged.
Raw scan report for this file
The main risk in this file is not out-of-bounds memory access (the Go scanner checks slice bounds) but **unsanitized cookie data reaching HTTP header serialization**. Cookie values, names, paths, and domains are written back into `Set-Cookie`/`Cookie` headers without rejecting or encoding delimiter characters such as `;`, `=`, and CRLF. This can allow cookie attribute injection, forged cookie name/value pairs, or HTTP header splitting when untrusted input is reflected into response or request headers.
Key flows:
- `Parse` / `ParseBytes` store raw `src` substrings into `c.key`, `c.value`, `c.domain`, and `c.path`.
- Setters such as `SetValue`, `SetDomain`, `SetKey`, and `SetPath` store caller-controlled strings into the same fields.
- `AppendBytes` serializes those fields directly into `dst`.
- `appendResponseCookieBytes` and `appendRequestCookieBytes` serialize caller-provided `argsKV` values directly into headers.
`SetPath` removes newlines but does **not** remove semicolons, so it can still be used for cookie attribute injection. `SetKey`, `SetValue`, and `SetDomain` do not remove newlines at all.
```json
[
{
"severity": "high",
"title": "Cookie attribute/header injection via unsanitized fields in AppendBytes",
"function": "Cookie.AppendBytes",
"description": "AppendBytes writes c.key, c.value, c.domain, and c.path directly to dst without rejecting or percent-encoding reserved characters. If an attacker can influence any of these fields through setters or parsed input, a value containing ';' can inject additional Set-Cookie attributes such as Domain, Path, SameSite, HttpOnly, or Secure, and CR/LF can split the HTTP header."
},
{
"severity": "high",
"title": "Set-Cookie injection in response cookie serializer",
"function": "appendResponseCookieBytes",
"description": "This function appends kv.value directly into the Set-Cookie header with no validation or encoding. If argsKV is built from untrusted input, a value containing ';' can inject additional Set-Cookie attributes, and CR/LF can inject arbitrary response headers."
},
{
"severity": "medium",
"title": "Cookie header injection in request cookie serializer",
"function": "appendRequestCookieBytes",
"description": "This function appends kv.key and kv.value directly into the request Cookie header. Untrusted keys or values containing ';' can add forged name=value pairs, and CR/LF can break the request header stream."
},
{
"severity": "high",
"title": "Missing delimiter and newline sanitization in cookie setters",
"function": "Cookie.SetKey/SetValue/SetDomain/SetPath",
"description": "These setters store raw caller-controlled strings in cookie fields. SetPath only removes newlines and does not reject semicolons, while SetKey, SetValue, and SetDomain do not remove newlines at all. The stored values are later serialized verbatim by AppendBytes, enabling cookie attribute injection and CRLF header injection."
},
{
"severity": "medium",
"title": "ParseBytes can retain CRLF from raw input",
"function": "Cookie.ParseBytes",
"description": "ParseBytes treats src as a flat cookie string and only splits on '=' and ';'. If src is attacker-controlled and contains CR/LF, those bytes can be stored in key, value, domain, or path. Later serialization via AppendBytes can reflect them as injected header lines. It also treats whitespace-only input as an empty valid cookie."
},
{
"severity": "low",
"title": "Max-Age integer wrap can alter cookie lifetime",
"function": "Cookie.ParseBytes",
"description": "Max-Age is parsed into an int via ParseUint with no visible overflow guard. A crafted very large Max-Age value can wrap to zero or negative, causing the cookie to be treated as having no Max-Age or as immediately deleted, potentially altering client-side cookie lifetime."
},
{
"severity": "low",
"title": "Parsed SameSite and Partitioned attributes bypass safety invariants",
"function": "Cookie.ParseBytes",
"description": "Parsing SameSite=None or Partitioned does not enforce the Secure, and Partitioned Path=/, invariants applied by SetSameSite and SetPartitioned. A parsed or reconstructed cookie can therefore carry insecure attribute combinations when serialized."
},
{
"severity": "low",
"title": "Quote-unaware cookie scanner truncates values",
"function": "cookieScanner.next/nextRaw",
"description": "The scanner does not recognize quoted cookie values and splits on every semicolon. A crafted Cookie or Set-Cookie value containing a semicolon inside quotes can be truncated or split, which may alter authentication or session cookie values seen by the application."
}
]
```