Skip to content

Strip IPv6 link-local zone id from absolute-form proxy request target - #13428

Open
Swastikbhat-lab wants to merge 4 commits into
aio-libs:masterfrom
Swastikbhat-lab:fix/ipv6-zone-proxy-request-line
Open

Strip IPv6 link-local zone id from absolute-form proxy request target#13428
Swastikbhat-lab wants to merge 4 commits into
aio-libs:masterfrom
Swastikbhat-lab:fix/ipv6-zone-proxy-request-line

Conversation

@Swastikbhat-lab

@Swastikbhat-lab Swastikbhat-lab commented Aug 15, 2026

Copy link
Copy Markdown

What type of PR is this? (check all applicable)

  • Bug Fix

Description

When a request to an IPv6 link-local URL with a zone id (e.g. http://[fe80::1%eth0]/) is sent through an HTTP proxy, aiohttp puts the zone id verbatim into the absolute-form request target of the request line:

GET http://[fe80::1%eth0]:8092/SerialNumber HTTP/1.1

Per RFC 6874 §4, the zone id only has local significance at the sending host and must be stripped from outgoing URIs — and %eth0 is not even valid URI syntax inside an IPv6 literal (RFC 3986). Strict proxies and gateways that validate the request target reject such requests, so the client gets a connection/400 failure even though the zone is required for routing at the socket layer.

This is the sibling of the Host-header leak already covered by #13409 (which strips the zone from the Host header and the CONNECT authority in _send()): the absolute-form branch in the same function still built the request target from the raw URL. This PR completes the RFC 6874 fix for that remaining path.

Related Issues / Pull Requests

Before/After

Before:

GET http://[fe80::1%eth0]:8092/SerialNumber HTTP/1.1

After:

GET http://[fe80::1]:8092/SerialNumber HTTP/1.1

Both the raw (%eth0) and RFC 6874-encoded (%25eth0) zone forms are covered.

Additional Context

  • The regression test fails on the unpatched tree with the zone visible in the captured status line, and passes with the fix (verified before/after).
  • tests/test_client_request.py, tests/test_client_functional.py, tests/test_client_session.py, tests/test_connector.py, tests/test_proxy.py, tests/test_proxy_functional.py: all green.

Checklist

  • I have read the CONTRIBUTING document.
  • I have added a change note in CHANGES/ (see CHANGES/README.rst).
  • I have added tests to cover my changes.
  • I have run the test suite locally.

@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label Aug 15, 2026
The absolute-form request target sent to an HTTP proxy was built from
str(self.url), which includes the IPv6 link-local zone id (e.g. %eth0).
Per RFC 6874 the zone id only has local significance at the sending
host and must be stripped from outgoing URIs; leaving it in the request
line makes the request invalid for strict proxies and servers.
@Swastikbhat-lab
Swastikbhat-lab force-pushed the fix/ipv6-zone-proxy-request-line branch from 622addb to 0ae8684 Compare August 15, 2026 22:56
@greptile-apps

greptile-apps Bot commented Aug 15, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported missing PR-numbered changelog symlink is present and correctly targets the issue-numbered fragment.

Reviews (4): Last reviewed commit: "Merge branch 'master' into fix/ipv6-zone..." | Re-trigger Greptile

Comment thread CHANGES/13401.bugfix.rst
Comment on lines +1 to +2
Strip the IPv6 link-local zone id from the absolute-form request
target sent to an HTTP proxy, per :rfc:`6874` -- by :user:`Swastikbhat-lab`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing PR-numbered changelog symlink

This issue-numbered fragment lacks the required CHANGES/13428.bugfix.rst symlink, so the repository's issue/PR changelog association does not include this pull request under its own number.

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@codecov

codecov Bot commented Aug 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.99%. Comparing base (e54b79c) to head (da3cc92).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #13428   +/-   ##
=======================================
  Coverage   98.99%   98.99%           
=======================================
  Files         132      132           
  Lines       49455    49473   +18     
  Branches     2571     2572    +1     
=======================================
+ Hits        48960    48978   +18     
  Misses        371      371           
  Partials      124      124           
Flag Coverage Δ
Autobahn 22.08% <10.52%> (-0.01%) ⬇️
CI-GHA 98.91% <100.00%> (+<0.01%) ⬆️
OS-Linux 98.68% <100.00%> (-0.01%) ⬇️
OS-Windows 97.03% <100.00%> (+<0.01%) ⬆️
OS-macOS 97.92% <100.00%> (+<0.01%) ⬆️
Py-3.10 98.12% <100.00%> (-0.01%) ⬇️
Py-3.11 98.38% <100.00%> (+<0.01%) ⬆️
Py-3.12 98.47% <100.00%> (+<0.01%) ⬆️
Py-3.13 98.45% <100.00%> (-0.01%) ⬇️
Py-3.14 98.47% <100.00%> (-0.01%) ⬇️
Py-3.14t 97.56% <100.00%> (-0.01%) ⬇️
Py-pypy-3.11 97.43% <100.00%> (+0.01%) ⬆️
VM-macos 97.92% <100.00%> (+<0.01%) ⬆️
VM-ubuntu 98.68% <100.00%> (-0.01%) ⬇️
VM-windows 97.03% <100.00%> (+<0.01%) ⬆️
cython-coverage 82.17% <0.00%> (-0.02%) ⬇️

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 Aug 15, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 84 untouched benchmarks
⏩ 83 skipped benchmarks1


Comparing Swastikbhat-lab:fix/ipv6-zone-proxy-request-line (da3cc92) with master (0660260)2

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.

  2. No successful run was found on master (e54b79c) during the generation of this report, so 0660260 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

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.

2 participants