JakeChampion / JakeChampion/trafficserver

[audit][perf] O(n^2) duplicate-check walk while parsing headers with many non-well-known field names

Open
#41 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:perf audit severity:high
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.