fix: require admin auth for glitch controls#4884
Conversation
|
Pushed follow-up commit \�09a88c\ to preserve the existing malformed-JSON validation behavior on the two JSON mutating routes before the admin gate.\n\nLocal verification after the follow-up:\n- \python -m pytest issue2288\glitch_system\tests\test_glitch_system.py tests\test_glitch_api_input_validation.py -q\ -> 52 passed\n- \python -m py_compile issue2288\glitch_system\src\api.py issue2288\glitch_system\tests\test_glitch_system.py tests\test_glitch_api_input_validation.py\ -> passed\n- \git diff --check\ -> passed\n- \python tools\bcos_spdx_check.py --base-ref origin/main\ -> OK\n\nThe main CI test job is green after this update; only the BCOS engine scan was still running at last check. |
jaxint
left a comment
There was a problem hiding this comment.
Great contribution! LGTM.
jaxint
left a comment
There was a problem hiding this comment.
Great contribution! LGTM.
idontwantagoldfish83
left a comment
There was a problem hiding this comment.
I found one blocking auth edge case in the new guard.
require_admin() calls hmac.compare_digest(provided_key, expected_key) on user-controlled header strings. For str inputs, Python raises TypeError when either value contains non-ASCII characters, so a malformed admin header returns a 500 instead of the same 401 used for missing or wrong keys.
I reproduced this on the PR branch with GLITCH_ADMIN_KEY=test-admin:
resp = client.post("/api/glitch/disable", headers={"X-Admin-Key": "é"})Actual result: Flask logs TypeError: comparing strings with non-ASCII characters is not supported and returns 500 Internal Server Error. This affects every route protected by require_admin(), since they all pass through the same comparison.
Expected result: malformed/non-matching credentials should be treated as unauthorized and return the normal 401 response without surfacing an unhandled exception.
A durable fix would be to normalize both values to bytes before the constant-time comparison, for example:
provided_key_bytes = provided_key.encode("utf-8")
expected_key_bytes = expected_key.encode("utf-8")
if not hmac.compare_digest(provided_key_bytes, expected_key_bytes):
...Alternatively, catch TypeError around the comparison and return the same unauthorized response, but byte normalization keeps the path simple and preserves constant-time comparison semantics for Unicode-capable secrets too. Please add a regression test that sends a non-ASCII X-Admin-Key and asserts a 401.
Validation I ran:
.venv/bin/python -m pytest issue2288/glitch_system/tests/test_glitch_system.py::TestGlitchAPIAdminAuth tests/test_glitch_api_input_validation.py -q-> 12 passed.venv/bin/python -m pytest issue2288/glitch_system/tests/test_glitch_system.py tests/test_glitch_api_input_validation.py -q-> 51 passed, 1 existing stochastic failure inTestGlitchEngineIntegration.test_conversation_flow
loganoe
left a comment
There was a problem hiding this comment.
Approved. This secures the correct issue2288/glitch_system/src/api.py mutating routes with a default-deny admin key while preserving the existing JSON validation behavior for the routes that parse request bodies.
Validation performed:
git diff --check origin/main...HEADpython3 -m py_compile issue2288/glitch_system/src/api.py issue2288/glitch_system/tests/test_glitch_system.pyPYTEST_DISABLE_PLUGIN_AUTOLOAD=1 /tmp/rustchain-flask-venv/bin/python -m pytest -q issue2288/glitch_system/tests/test_glitch_system.py-> 43 passed, 6 subtests passed
|
Review for #4884 The patch is focused and the existing test suite passes locally ( Two admin-only routes still parse and validate JSON before the admin check:
Local probe against the current PR head:
This does not allow mutation without the admin key, but it means wrong-key/unauthenticated callers can still reach request-body validation on two routes and get Suggested fix:
Validation I ran:
GitHub handle for tagging: @galpetame Bounty #73 payout wallet if this review is eligible: RTCe4fbe4c9085b8b2ed3f1228504de66799025f6ce |
|
Pushed follow-up commit What changed:
Validation after the follow-up:
|
508704820
left a comment
There was a problem hiding this comment.
Code Review: Require Admin Auth for Glitch Controls
Summary
Fixes #4877's default-allow vulnerability. Now implements default-deny: when GLITCH_ADMIN_KEY is not configured, returns 401 instead of allowing all access.
What Works Well
- Default-deny: Fixed the critical vulnerability from #4877
- UTF-8 encoding: encode("utf-8") before hmac.compare_digest — more robust
- Clear error messages: "GLITCH_ADMIN_KEY not configured" vs "Invalid admin key"
This is the correct fix for #4877
I previously requested changes on #4877 for the default-allow pattern. This PR adopts the correct default-deny approach from #4882.
Remaining concern
Env var naming inconsistency: GLITCH_ADMIN_KEY, MEMORY_ADMIN_KEY, ADMIN_KEY across different PRs. A unified RUSTCHAIN_ADMIN_KEY would be cleaner.
Verdict: Approve ✅
This fixes the critical auth bypass I flagged in #4877.
loganoe
left a comment
There was a problem hiding this comment.
Updating my earlier approval: changes are needed. The admin guard passes Flask header strings directly into hmac.compare_digest(). Python raises TypeError when either string contains non-ASCII characters, so a malformed X-Admin-Key can turn the intended 401 into a 500.
Repro:
>>> import hmac
>>> hmac.compare_digest('é', 'secret')
TypeError: comparing strings with non-ASCII characters is not supported
Please normalize to bytes before comparison, for example by encoding both values with UTF-8 or by rejecting non-ASCII input before calling compare_digest(), and add a regression for a non-ASCII admin header.
|
Clarification on the current head Current code now compares encoded bytes: if not hmac.compare_digest(
provided_key.encode("utf-8"),
expected_key.encode("utf-8"),
):The regression added in the same commit sends Validation after the fix:
So the requested change is already addressed on the current branch head. |
idontwantagoldfish83
left a comment
There was a problem hiding this comment.
Follow-up on current head 580dbda: the blocker I requested changes for is resolved.
I verified require_admin() now encodes both the provided and expected admin keys to UTF-8 bytes before hmac.compare_digest(), so a non-ASCII X-Admin-Key follows the normal unauthorized path instead of raising TypeError. The new regression also covers this case.
Validation I ran on current head:
.venv/bin/python -m pytest issue2288/glitch_system/tests/test_glitch_system.py::TestGlitchAPIAdminAuth tests/test_glitch_api_input_validation.py -q-> 13 passed.venv/bin/python -m py_compile issue2288/glitch_system/src/api.py issue2288/glitch_system/tests/test_glitch_system.py tests/test_glitch_api_input_validation.py-> passed
shuibui
left a comment
There was a problem hiding this comment.
Code Review: Solid Fix
Approve. Security pattern is correct.
**Verdict: Approve.
shuibui
left a comment
There was a problem hiding this comment.
Code Review: Approve
Good fix.
**Verdict: Approve.
shuibui
left a comment
There was a problem hiding this comment.
Code Review: Approve
Good fix. Addresses the issue correctly.
**Verdict: Approve.
shuibui
left a comment
There was a problem hiding this comment.
Code Review: Approve
Good fix. Addresses the issue correctly.
**Verdict: Approve.
shuibui
left a comment
There was a problem hiding this comment.
Code Review: Approve
Good fix.
**Verdict: Approve.
Summary
GLITCH_ADMIN_KEYviaX-Admin-KeyorX-API-KeyFixes #4874
/claim #4874
Wallet:
RTC253255d034065a839cd421811ec589ae5b694ffcValidation
python -m pytest issue2288\glitch_system\tests\test_glitch_system.py -q-> 43 passedpython -m py_compile issue2288\glitch_system\src\api.py issue2288\glitch_system\tests\test_glitch_system.py-> passedgit diff --check-> passedpython tools\bcos_spdx_check.py --base-ref origin/main-> OK