# curl — CWE-407 Disclosure Brief
**2026-03-27 · Patch available — awaiting upstream merge**

## Finding

One O(n²) defect in curl's cookie engine. `replace_existing()` in `lib/cookie.c` performs a linked-list scan over all cookies in a bucket on every cookie insert, causing O(C²) total overhead per bucket during cookie-heavy sessions. Patch ready for upstream review.

## The Defects

**curl-0001 (PATCHED — HIGH):** `lib/cookie.c`

```c
/* replace_existing() — per cookie bucket insert: */
static struct Cookie *
replace_existing(struct Curl_easy *data, struct CookieInfo *c,
                 const struct Cookie *co)
{
    /* O(C) linked-list scan per insert */
    struct Cookie *clist = c->cookies[hash];
    while (clist) {
        if (strcasecompare(clist->name, co->name) && ...) {
            return clist;  /* found — replace */
        }
        clist = clist->next;
    }
    return NULL;
}
/* O(C²) per bucket when inserting C cookies */
```

Linked-list scan O(C) per bucket per insert. For C cookies per bucket: **O(C²) total**. Fix: per-bucket `HashMap<name, node>`.

## Complexity Proof

For C cookies per hash bucket:
- Per insert: O(C) linked-list walk
- C inserts: O(C²) per bucket
- Fixed: `HashMap<name, Cookie*>` per bucket → O(C) total
- Scales with cookie jar size; session-heavy applications most affected.

## Impact

All curl users making requests to cookie-heavy websites — authentication flows, session management, web scraping, API clients, and browser-like applications. `replace_existing()` fires on every `Set-Cookie` header processed. Applications that accumulate large cookie jars (many `Set-Cookie` headers per session, many domains) hit O(C²) per bucket. curl is used in virtually every software stack as the de-facto HTTP client.

## The Fix

Replace the linked-list bucket scan with `HashMap<name, Cookie*>` per bucket:

```c
/* Before */
struct Cookie *clist = c->cookies[hash];
while (clist) {
    if (strcasecompare(clist->name, co->name)) return clist;
    clist = clist->next;
}

/* After */
/* CWE-407 fix: per-bucket HashMap for O(1) lookup instead of O(C) linked-list scan. */
struct Cookie *existing = Curl_hash_pick(&c->cookie_hash[hash],
                                          co->name, strlen(co->name) + 1);
return existing;
```

## Patch

`defects/curl/patch/curl-0001-cookie-replace-hashmap.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your cookie engine test suite.
3. Assess CVE eligibility — fires on every Set-Cookie header in cookie-heavy sessions.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.
