fix(server): make is_composite_global_id reject non-base64 input gracefully#12943
Open
GopalGB wants to merge 1 commit intoArize-ai:mainfrom
Open
fix(server): make is_composite_global_id reject non-base64 input gracefully#12943GopalGB wants to merge 1 commit intoArize-ai:mainfrom
GopalGB wants to merge 1 commit intoArize-ai:mainfrom
Conversation
Contributor
|
All contributors have signed the CLA ✍️ ✅ |
0b4fc05 to
e1408cb
Compare
Author
|
Force-pushed after re-authoring the commit under I have read the CLA Document and I hereby sign the CLA |
Author
|
recheck I have read the CLA Document and I hereby sign the CLA |
…acefully
Navigating to `/projects/<name>/*` URLs (e.g. `/projects/default/traces`)
fired a `node` GraphQL query with the literal project NAME as the id.
`is_composite_global_id("default")` then called `b64decode("default")`
directly, which raised `binascii.Error: Incorrect padding` and bubbled
up as a generic "Something went wrong" error in the UI.
Reproducer (against `main`):
```python
>>> from phoenix.server.api.types.node import is_composite_global_id
>>> is_composite_global_id("default")
binascii.Error: Incorrect padding
```
Fix:
* `is_composite_global_id` now uses `b64decode(node_id, validate=True)`
inside a `try / except (binascii.Error, UnicodeDecodeError, ValueError)`
block and returns `False` for any input that is not valid base64 or
whose decoded bytes are not valid UTF-8. Non-base64 strings are by
definition not composite global ids.
* `Query.node` now wraps `GlobalID.from_id(id)` in a `try / except` and
raises a friendly `NotFound(f"Unknown node: {id}")` instead of leaking
a `GlobalIDValueError`-shaped padding error to the client.
Adds 5 new test cases in `tests/unit/server/api/types/test_node.py`:
- `test_is_composite_global_id_returns_false_for_non_base64_input`
- `test_is_composite_global_id_handles_invalid_base64` (parametrized
over "default", "my-project-name", "abc", "", "===", "not!base64")
- `test_is_composite_global_id_returns_false_for_simple_global_id`
- `test_is_composite_global_id_returns_true_for_composite_id`
- `test_is_composite_global_id_handles_non_utf8_decoded_bytes`
Closes Arize-ai#12908
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: GopalGB <67310594+GopalGB@users.noreply.github.com>
e1408cb to
c4b689a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Repro
Phoenix 14.15.0. Navigate to
http://localhost:6006/projects/default/traces(or any
/projects/<name>/*route using the project NAME instead of thebase64 global id):
Server-side stack trace:
Standalone reproducer (
mainHEAD):Fix
is_composite_global_idcallsb64decodedirectly without checkingwhether the string is valid base64. "default" contains an invalid char
(
u) for the standard base64 alphabet AND wrong padding length, so theexception bubbles up as a generic GraphQL error.
is_composite_global_idnow usesb64decode(node_id, validate=True)inside a
try / except (binascii.Error, UnicodeDecodeError, ValueError)block and returns
Falsefor any input that is not valid base64 orwhose decoded bytes are not valid UTF-8. Non-base64 strings are by
definition not composite global ids.
Query.nodenow wrapsGlobalID.from_id(id)in atry / exceptandraises a friendly
NotFound(f"Unknown node: {id}")instead of leakinga
GlobalIDValueError-shaped padding error to the client.Diff:
Test
5 new test cases in
tests/unit/server/api/types/test_node.py:test_is_composite_global_id_returns_false_for_non_base64_input--the exact
"default"regression.test_is_composite_global_id_handles_invalid_base64-- parametrizedover
"default","my-project-name","abc","","===","not!base64".test_is_composite_global_id_returns_false_for_simple_global_id--b64encode(b"Project:1")is not composite (single:).test_is_composite_global_id_returns_true_for_composite_id--b64encode(b"ExperimentRepeatedRunGroup:1:2")IS composite.test_is_composite_global_id_handles_non_utf8_decoded_bytes--random base64 that decodes to non-UTF-8 must not raise.
Verified locally that the fix function returns
Falsefor every inputin the parametrized set; verified the bug reproduces on the unmodified
mainbranch (the standalone reproducer above raisesbinascii.Error: Incorrect padding).Closes #12908