JakeChampion / JakeChampion/trafficserver
[audit][perf] O(n^2) duplicate-check walk while parsing headers with many non-well-known field names
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 0
- Forks
- 0
- Avg merge
- 8h 2m
- Merged PRs (30d)
- 21
Description
Severity: high · Category: performance
Location: src/proxy/hdrs/MIME.cc:1396
What's wrong
Every field parsed by mime_parser_parse is attached with check_for_dups=1 (MIME.cc:2573 'mime_hdr_field_attach(mh, field, 1, nullptr)'), and mime_hdr_field_attach then calls mime_hdr_field_find for the new field's name. For names that are not well-known tokens (no presence bits, no slot accelerator), mime_hdr_field_find falls through to _mime_hdr_field_list_search_by_string (MIME.cc:1156-1177), which walks every field slot in every block doing ts::iequals. With k distinct custom header names in one message this makes header parsing O(k^2). There is no header field-count limit (only proxy.config.http.request_header_max_size, default 32768), so a 32KB request of ~3500 short distinct custom headers forces ~6M slot visits with case-insensitive compares — attacker-controlled milliseconds of CPU per request on every net thread, on both the request parse and the origin response parse. WKS fields whose slot id exceeds the accelerator range hit the same full walk via _mime_hdr_field_list_search_by_wks (MIME.cc:1133-1153).
Evidence
MIME.cc:1394-1396: if (check_for_dups || ...) { std::string_view name{field->name_get()}; prev_dup = mime_hdr_field_find(mh, name);
MIME.cc:1269: MIMEField *f = _mime_hdr_field_list_search_by_string(mh, field_name);
MIME.cc:1162-1173: for (fblock = &(mh->m_first_fblock); fblock != nullptr; fblock = fblock->m_next) { ... while (field < too_far_field) { if (field->is_live() && ts::iequals(...)) ...
Suggested fix
Bound the quadratic behavior: keep a small per-parse hash of seen non-WKS names (or a per-header presence filter) so the dup check is O(1) amortized; alternatively add a configurable max field count and skip the dup search during initial parse by attaching with check_for_dups=0 and linking dups in a single post-pass.
Filed from an automated multi-lens codebase audit. Full report: CODEBASE_AUDIT.md / audit-report.html on branch claude/codebase-audit-review-9nw7vz.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/proxy/hdrs/MIME.cc at the duplicate check around lines 1394-1396, then trace mime_hdr_field_attach and the string and WKS search helpers around lines 1133-1177 and 1269. Confirm the behavior with many distinct custom headers and ensure duplicate detection remains correct while the parse-time lookup no longer performs a quadratic walk; CODEBASE_AUDIT.md and audit-report.html provide the broader audit context.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend-api-design, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100