Skip to content

Commit 7144c52

Browse files
vvillait88claude
andcommitted
hardening(examples): sanitize UCP self-test exception, drop unused Any import
CodeQL flagged the `/_selftest/ucp` route returning `str(exc)` to the HTTP response body as information exposure. Match the round-26 sanitization pattern used in core/store: log the full exception server-side via logger.exception, expose only `type(exc).__name__` + the structured verification code to the caller. The error class name is enough for an operator to triage without revealing internal verification machinery. Also drop the unused `Any` import from tests/test_ucp.py; the only cast() target gets retyped to `OperatorVerification` (the actual field type), which keeps the typed-empty-wins-over-raw test intent intact. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4b9571e commit 7144c52

2 files changed

Lines changed: 7 additions & 3 deletions

File tree

examples/signed_ucp_merchant.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,8 @@ async def selftest() -> JSONResponse:
141141
verify_ucp_profile(profile, jwks)
142142
return JSONResponse({"ok": True, "kid": profile["signing_keys"][0]["kid"]})
143143
except UCPVerificationError as exc:
144-
return JSONResponse({"ok": False, "code": exc.code, "message": str(exc)}, status_code=500)
144+
logger.exception("UCP self-test verification failed")
145+
return JSONResponse(
146+
{"ok": False, "code": exc.code, "error": type(exc).__name__},
147+
status_code=500,
148+
)

tests/test_ucp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Tests for build_ucp_profile."""
22

3-
from typing import Any, cast
3+
from typing import cast
44

55
import pytest
66

@@ -386,7 +386,7 @@ def test_typed_empty_operator_verification_wins_over_raw() -> None:
386386
allow=True,
387387
resolved_operator="op_xyz",
388388
# Empty dict is a valid typed value (means "operator block returned empty").
389-
operator_verification=cast("Any", {}),
389+
operator_verification=cast("OperatorVerification", {}),
390390
raw={"operator_verification": {"level": "enhanced", "verified_at": "2026-01-01T00:00:00Z"}},
391391
)
392392
profile = build_ucp_profile(**_base_kwargs(), data=result)

0 commit comments

Comments
 (0)