fix(auth): compare API keys at the raw ASGI boundary - #520
Conversation
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughAPI 키 검증이 문자열 비교에서 UTF-8 바이트 비교로 변경되었습니다. 비ASCII API 키 헤더의 401 응답을 검증하는 회귀 테스트와 보안 학습 문서가 추가되었습니다. ChangesAPI 키 검증
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…- Fixes a 500 error in `hmac.compare_digest` where non-ASCII API keys\n (e.g., Unicode sequences) raised a `TypeError` by explicitly extracting\n and decoding raw ASGI byte strings.\n- Prevents HTTP header injection / ambiguity bypasses by strictly failing\n closed if multiple `X-API-Key` headers are provided.
Current repair boundary
The weak fix for
hmac.compare_digest(str, str)is to re-encode Starlette's decoded header string. That can corrupt the credential boundary and does not resolve duplicate-header ambiguity. This canonical lane instead authenticates from the raw ASGI header bytes: exactly oneX-API-Keyis accepted and compared in constant time with each configured UTF-8 key.Current protected
main:47c6fd27de13b0da37a7db64697b869941909351.Current exact head:
08d1c3ca20e3e41a703ac9e5c5aea6f702962d2d.Fresh compare: ahead 13 / behind 0, merge base exactly current protected
main.Lifecycle: Draft.
Effective protected-base delta is now exactly five paths; the earlier generated
.jules/sentinel.mdchange has been removed from the current diff:CHANGELOG.md;saas_web.py;tests/test_api_key_header_multiplicity.py;tests/test_api_key_unicode_contract.py;tests/test_saas_web.py.RED → GREEN
안녕with identical raw UTF-8 header bytes must reach the protected handler;compare_digest;X-API-Keyheaders must fail closed whether their values match or differ;_raw_api_key_header()readsrequest.scope['headers']directly and authorizes only one raw value. The middleware compares that byte sequence with configured UTF-8 key bytes usinghmac.compare_digest. The focused regressions cover valid Unicode, wrong Unicode/high-bit input, and duplicate authority. The CHANGELOG records the public credential-boundary behavior.Sibling #527's only valid non-ASCII 500→401 intent/regression is fully superseded here; #527 was closed only after that succession was verified. Its blanket “always encode user-controlled strings before
compare_digest” doctrine and unsupported CRITICAL/process-crash framing were not inherited.Remaining governance finding
CODEC_CARVER_API_KEYSis still an environment-variable credential registry. That existing governance finding is independent of the transport-encoding repair and remains a promotion blocker until it is repaired here or completely inherited by a canonical successor. Do not dilute the raw-header fix by reverting to framework-decoded credential authority.Exact-head hosted evidence and foreign-owner RCA
On exact
08d1c3ca20e3e41a703ac9e5c5aea6f702962d2d:33905349122: success;33905349153: success;33905349127: success;33905348978: success;33905348976: failure.The CodeQL failure is central control-plane evidence, not a local source failure. Detect job
101128928869succeeded on the exact head. Both compatibility jobs successfully requested current-head dispatch, then failed atFail closed without a current-head CodeQL dispatch verdict: python job101188835268, actions job101188835300. The owner-path evidence has been handed to dedicated.githubrepair lane #1902. Leaf no-op commits, synthetic status, gate weakening, or broad timeout changes are not authorized substitutes.Keep Draft until the unchanged exact head receives authenticated terminal CodeQL verdicts after the central repair, the credential-registry governance finding is resolved or canonically inherited, all valid review threads are resolved, and live protection has qualifying independent approval.
No self-approval, administrator bypass, force push, destructive rebase, or predecessor-evidence transfer.