4.5 KiB
Eclipse Jetty — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in Eclipse Jetty's HTTP field parsing. QuotedCSV.getValues() uses LinkedList.contains() for deduplication inside a loop over parsed values, producing quadratic behavior during HTTP header parsing. Fix: LinkedHashSet. Patched. Measured ratio: 50×.
The Defects
jetty-0001 (PATCHED — HIGH): jetty-http/src/main/java/.../HttpFields.java
// QuotedCSV.getValues() — called per HTTP header field containing comma-separated values:
LinkedList<String> values = new LinkedList<>();
for (String item : parsedItems) { // O(n) outer — n parsed CSV tokens
if (!values.contains(item)) { // O(n) LinkedList.contains() scan
values.add(item); // dedup: skip if already seen
}
}
// O(n²) total — n = number of values in the CSV header field
QuotedCSV.getValues() deduplicates parsed CSV values using LinkedList.contains() inside the accumulation loop. LinkedList.contains() performs a full O(n) sequential scan for each new item. For n values in the CSV field: O(n²) total. Fix: replace LinkedList<String> with LinkedHashSet<String> — preserves insertion order, O(1) contains(), drops duplicates automatically. Measured ratio: 50×.
Complexity Proof
Let n = number of comma-separated token values in a single HTTP header field (e.g., Accept, Accept-Encoding, Cache-Control, Vary, Te, custom multi-value headers).
- Defective: for each of n items,
LinkedList.contains()scans up to all previously added items.- Total comparisons: 1 + 2 + ... + (n-1) = n(n-1)/2 ≈ O(n²).
LinkedList.contains()is O(k) for k elements currently in the list — no hash, no skip.
- Fixed:
LinkedHashSet.contains()→ O(1) amortized per check.- Total: O(n) for all n items.
- Insertion order preserved (matches original
LinkedListcontract).
At n=50 values per header: defective=1,225 comparisons, fixed=50 hash lookups. 50× measured ratio.
HTTP headers such as Accept, Accept-Encoding, and Vary commonly contain 5–20 values; malformed or adversarial requests can contain far more. The QuotedCSV.getValues() path is exercised on every request that triggers multi-value header parsing.
Impact
All Eclipse Jetty deployments — any application server, embedded Jetty instance, or HTTP client using Jetty's HttpFields.QuotedCSV.getValues() for multi-value header parsing. This includes:
- Spring Boot applications (Jetty is an alternate embedded servlet container to Tomcat)
- Applications using Jetty HTTP client for outbound requests with multi-value response headers
- Jetty-based gateways and reverse proxies parsing
Accept,Accept-Encoding,Cache-Control, and custom multi-value headers
The defect fires on every request or response that triggers QuotedCSV.getValues(). Under adversarial input (large comma-separated header values), this becomes a denial-of-service vector proportional to n² where n is attacker-controlled.
The Fix
Replace LinkedList<String> with LinkedHashSet<String> in QuotedCSV.getValues():
// Before
LinkedList<String> values = new LinkedList<>();
for (String item : parsedItems) {
if (!values.contains(item)) { // O(n) LinkedList scan — CWE-407
values.add(item);
}
}
return values;
// After
// CWE-407 fix: LinkedHashSet for O(1) contains() with preserved insertion order.
LinkedHashSet<String> values = new LinkedHashSet<>();
for (String item : parsedItems) {
values.add(item); // add() is no-op for duplicates — O(1) implicit dedup
}
return new ArrayList<>(values); // or return List.copyOf(values) — caller contract preserved
LinkedHashSet maintains insertion order (matching the original LinkedList semantics) while providing O(1) hash-based duplicate detection. No functional change — only algorithmic complexity changes from O(n²) to O(n).
Patch
defects/jetty/patch/jetty-0001-http-fields-quotedcsv-linkedhashset.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference (eclipse/jetty.project).
- Validate the patch against the
HttpFieldsandQuotedCSVtest suites. - Assess CVE eligibility — jetty-0001 is potentially a denial-of-service vector under adversarial header input (attacker-controlled n).
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.