java-topology/defects/curl/patch/curl-0003-hsts-hashmap.md

51 lines
1.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000583
# curl-0003: Curl_hsts O(N) linked-list scan → O(1) hash map
## Classification
| Field | Value |
|-------------|-------|
| CWE | CWE-407 Inefficient Algorithmic Complexity |
| Severity | MEDIUM |
| Component | `lib/hsts.c:225` (`Curl_hsts`), `lib/hsts.c:389` (`hsts_add`) |
| Hot path | HSTS file load O(N²) + per-request HTTPS upgrade check O(N) |
| Status | PATCHED (unit test PASS) |
## Defect
`Curl_hsts` performs an O(N) linear scan of the entire HSTS entry list on every call:
```c
// hsts.c:225
struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, ...) {
for(e = Curl_llist_head(&h->list); e; e = n) { // O(N) every call
struct stsentry *sts = Curl_node_elem(e);
if((hlen == ntail) && curl_strnequal(hostname, sts->host, hlen))
return sts;
}
return NULL;
}
```
**Two O(N²) impact paths:**
1. **File load** (`hsts_load``hsts_add``Curl_hsts` for dedup): N calls, each
O(N) → **O(N²)** total. A 1,000-entry HSTS file performs 500,000 comparisons.
2. **Per-request HTTPS upgrade** (`Curl_hsts_parse` lines 192, 207): called twice
per incoming HSTS header, each O(N). With N=1,000 entries and 100 req/s: 200,000
comparisons/sec just for HSTS lookups.
## Fix
Replace `Curl_llist` in `struct hsts` with a hash table keyed on hostname (case-insensitive):
```c
// hsts_add: O(1) insert
// Curl_hsts: O(1) lookup
struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, ...) {
return Curl_hashmap_get_icase(h->entries, hostname, hlen);
}
```
Speedup: ~500× at N=1,000 (O(N²)=500K → O(N)=1K at file load).