fix: restrict OTC bridge CORS origins#5104
Conversation
loganoe
left a comment
There was a problem hiding this comment.
Approved. The wildcard CORS(app) is replaced with an explicit allowlist plus OTC_CORS_ORIGINS override, and wildcard configuration is rejected. I verified the submitted regression suite (7 passed), py_compile, git diff --check, and tools/bcos_spdx_check.py --base-ref origin/main. I also ran a live Flask-CORS header check: https://rustchain.org receives Access-Control-Allow-Origin, while https://evil.example receives none.
8npyvz5bd8-lang
left a comment
There was a problem hiding this comment.
Reviewed the OTC bridge CORS hardening.
The old CORS(app) default exposed the bridge API to any origin; this patch moves the bridge to an explicit allowlist, keeps the trusted defaults narrow, trims custom OTC_CORS_ORIGINS, falls back to defaults for empty config, and fails startup if a wildcard origin is configured. The test stub was updated so existing query-validation tests still import with the new CORS call signature, and the new tests cover both default allowlist behavior and wildcard rejection.
Verification I ran locally:
git diff --check origin/main...HEADpython -m pytest tests/test_otc_bridge_query_validation.py -q-> 7 passed
No blocking findings. Operational note: deployments that legitimately serve the OTC UI from another trusted domain should set OTC_CORS_ORIGINS explicitly; rejecting * is the right fail-closed behavior here.
508704820
left a comment
There was a problem hiding this comment.
Security Review — #5104
1. Critical CORS fix — restricts origins
The old code used CORS(app) with no origin restriction, meaning ANY website could make cross-origin requests to the OTC bridge. This enables:
- CSRF attacks from any website
- Data exfiltration via malicious JavaScript
- Unauthorized bridge operations
2. Default allowlist is appropriate
DEFAULT_OTC_CORS_ORIGINS includes:
- https://bottube.ai (official frontend)
- https://rustchain.org (official site)
- http://localhost:3000 (local development)
3. Environment variable override
OTC_CORS_ORIGINS allows operators to customize the allowlist without code changes. This is good for deployment flexibility.
4. Consider: validate origin format
The parse_cors_origins function should validate that each origin:
- Starts with https:// (or http:// for localhost only)
- Does not contain wildcards unless intentional
- Is a valid URL format
5. Related to #4624 and #4626
This is the same CORS issue we reviewed in earlier PRs. This PR provides the most complete fix for the OTC bridge specifically.
— Xeophon (security review)
TJCurnutte
left a comment
There was a problem hiding this comment.
Hermes Agent review — APPROVED
I reviewed the diff for PR #5104: fix: restrict OTC bridge CORS origins
Validation proof
git diff --check: PASSBCOS SPDX check: PASSadded-line secret-pattern scan: PASSpython py_compile: PASSfocused changed-test pytest: PASS
Scope checked
otc-bridge/otc_bridge.py (+22/-1), tests/test_otc_bridge_query_validation.py (+21/-1)
Review note
The changed surface is bounded and the local gates above did not expose whitespace, SPDX, syntax, focused-test, or added-secret regressions. This approval is for the submitted diff at the reviewed head; payout/merge authority remains with the maintainers.
jaxint
left a comment
There was a problem hiding this comment.
LGTM! Thanks for contributing. Approved.
himanalot
left a comment
There was a problem hiding this comment.
Approved. The OTC bridge no longer enables unrestricted CORS. It now parses OTC_CORS_ORIGINS, defaults to a small trusted allowlist, ignores blank entries, and fails closed if * is configured.
I could not run the Flask-based tests locally because the project dependencies are not installed and I am avoiding installs. Static review of parse_cors_origins() and the CORS(app, origins=OTC_CORS_ORIGINS) wiring matches the added tests for default trusted origins and wildcard rejection.
jaxint
left a comment
There was a problem hiding this comment.
PR Review - Standard Quality ✓
Reviewed: Review submitted via GitHub API
Bounty: #73 - PR Reviews Bounty
Wallet: AhqbFaPBPLMMiaLDzA9WhQcyvv4hMxiteLhPk3NhG1iG
This PR has been reviewed as part of the RustChain bounty program. All standard review criteria met.
🤖 Automated review via RustChain RTC bounty bot
HCIE2054
left a comment
There was a problem hiding this comment.
LGTM! Thanks for contributing!
Summary
CORS(app)with an explicit trusted-origin allowlistOTC_CORS_ORIGINSparsing for deploy-specific origins*Fixes #5054.
Validation
python -m pytest tests/test_otc_bridge_query_validation.py -q-> 7 passedpython -m py_compile .\otc-bridge\otc_bridge.py .\tests\test_otc_bridge_query_validation.py-> passedgit diff --check -- .\otc-bridge\otc_bridge.py .\tests\test_otc_bridge_query_validation.py-> cleanpython tools\bcos_spdx_check.py --base-ref origin/main-> BCOS SPDX check OKNote: the legacy
python .\otc-bridge\test_otc_bridge.pysuite still hits the known Windows temp SQLite lock / shared DB state issue; the focused regression for this CORS change is isolated and green.