fix quadratic parsing of WWW-Authenticate challenge in _parse_challenge#47935
fix quadratic parsing of WWW-Authenticate challenge in _parse_challenge#47935nabhan06 wants to merge 1 commit into
Conversation
|
Thank you for your contribution @nabhan06! We will review the pull request and get back to you soon. |
|
@nabhan06 please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
There was a problem hiding this comment.
Pull request overview
This PR fixes a quadratic-time (ReDoS-style) parsing vulnerability in the container registry auth bootstrap. The WWW-Authenticate challenge header from a registry's unauthenticated 401 response is parsed in _parse_challenge (_helpers.py). The previous pattern (?:(\w+)="([^"]*)")+ used with re.split backtracked over long runs of word characters not followed by =", so an oversized challenge cost O(n²) — and this executes before the client is authenticated. The fix anchors each key/value pair to the start or a whitespace/comma separator and switches to finditer, which scans the header once. I verified that valid challenges still parse to the same realm/service/scope keys consumed by callers (_exchange_client.py and async/anonymous variants), and that the adversarial input now fails in constant time per position.
Changes:
- Replaced the backtracking-prone regex +
re.split+_cleanhelper with an anchored pattern parsed viafinditer, removing the now-unused_cleanfunction andListimport. - Added two unit tests: a normal challenge and an adversarial 100k-char header regression guard.
- Added a CHANGELOG entry under
1.2.1 (Unreleased)→ Bugs Fixed.
I confirmed the List import removal is safe (no remaining usage in _helpers.py), the tests are placed in the credential-free TestContainerRegistryClientUnitTests class, and the callers still receive the expected keys.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
azure/containerregistry/_helpers.py |
Anchored the challenge regex, switched to finditer, and removed the now-unused _clean helper and List import to eliminate O(n²) parsing. |
tests/test_container_registry_client.py |
Added unit tests for a normal challenge and an adversarial oversized header. |
CHANGELOG.md |
Documented the fix under 1.2.1 Bugs Fixed. |
|
@microsoft-github-policy-service agree company="BugQore" |
Description
Quadratic parsing of the container registry challenge header
The auth bootstrap parses the
WWW-Authenticateheader from the registry's 401 response in_parse_challenge(azure/containerregistry/_helpers.py). The regex was applied withre.split, and(?:(\w+)="([^"]*)")+backtracks over a long run of word characters that isn't followed by=", so a registry that returns an oversized challenge makes parsing cost O(n^2) — this runs before the client is authenticated. Anchored the pattern to a separator/start and switched tofinditer, which walks the header once. Valid challenges parse to the same result; the_cleanhelper is no longer needed.A 100k-char header goes from tens of seconds to a couple of milliseconds. Added a unit test in
TestContainerRegistryClientUnitTestscovering both a normal challenge and the adversarial one.All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines