Skip to content

fix infinite loop parsing the Forwarded header#13229

Draft
arshsmith1 wants to merge 1 commit into
aio-libs:masterfrom
arshsmith1:forwarded-parse-infinite-loop
Draft

fix infinite loop parsing the Forwarded header#13229
arshsmith1 wants to merge 1 commit into
aio-libs:masterfrom
arshsmith1:forwarded-parse-infinite-loop

Conversation

@arshsmith1

Copy link
Copy Markdown
Contributor

What do these changes do?

BaseRequest.forwarded walks each Forwarded header with a hand-written cursor loop. When a segment neither matches _FORWARDED_PAIR_RE nor has a following ;, field_value.find(";", pos) returns -1, so the empty-value branch sets pos = -1 + 1 = 0 and the cursor jumps back to the start. The loop then never makes progress and spins at 100% CPU on the event loop thread. A single header such as Forwarded: a (also for=1.2.3.4; a, for=_; x, ; a) is enough to hang the worker permanently. Reading request.forwarded is common in reverse-proxy setups, so any middleware or handler that touches it exposes this.

The loop now breaks when there is no further ; to consume, since a trailing empty-or-malformed value ends the field-value either way. That also drops the off-by-one where the old [pos : field_value.find(";", pos)] slice quietly cut the last character when no ; was present.

Are there changes in behavior for the user?

No API change. Well-formed and previously-terminating headers parse exactly as before; the only difference is that the pathological inputs now terminate and return the valid prefix instead of hanging.

Is it a substantial burden for the maintainers to support this?

No. It touches the one parse loop and adds a parametrized regression test next to the existing Forwarded tests.

Related issue number

None.

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes — N/A, no public API change
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
  • Add a new news fragment into the CHANGES/ folder

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 98.98%. Comparing base (76bb64e) to head (7cbe0aa).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
aiohttp/web_request.py 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #13229      +/-   ##
==========================================
- Coverage   98.98%   98.98%   -0.01%     
==========================================
  Files         131      131              
  Lines       48993    48999       +6     
  Branches     2550     2551       +1     
==========================================
+ Hits        48496    48500       +4     
- Misses        373      374       +1     
- Partials      124      125       +1     
Flag Coverage Δ
Autobahn 22.12% <25.00%> (+<0.01%) ⬆️
CI-GHA 98.89% <87.50%> (-0.01%) ⬇️
OS-Linux 98.66% <87.50%> (-0.01%) ⬇️
OS-Windows 97.02% <87.50%> (-0.01%) ⬇️
OS-macOS 97.92% <87.50%> (-0.02%) ⬇️
Py-3.10 98.11% <87.50%> (-0.01%) ⬇️
Py-3.11 98.37% <87.50%> (-0.01%) ⬇️
Py-3.12 98.46% <87.50%> (-0.01%) ⬇️
Py-3.13 98.43% <87.50%> (-0.02%) ⬇️
Py-3.14 98.45% <87.50%> (-0.01%) ⬇️
Py-3.14t 97.55% <87.50%> (-0.02%) ⬇️
Py-pypy-3.11 97.38% <87.50%> (-0.01%) ⬇️
VM-macos 97.92% <87.50%> (-0.02%) ⬇️
VM-ubuntu 98.66% <87.50%> (-0.01%) ⬇️
VM-windows 97.02% <87.50%> (-0.01%) ⬇️
cython-coverage 37.93% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@codspeed-hq

codspeed-hq Bot commented Jul 23, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 83 untouched benchmarks
⏩ 83 skipped benchmarks1


Comparing arshsmith1:forwarded-parse-infinite-loop (7cbe0aa) with master (76bb64e)

Open in CodSpeed

Footnotes

  1. 83 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@arshsmith1
arshsmith1 force-pushed the forwarded-parse-infinite-loop branch from 8b5fd88 to 7cbe0aa Compare July 23, 2026 08:50
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant