Harden internet-facing indexer production checklist and CORS bind guard #326
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#326
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
GitLab #325 — Security review (audit finding F-04, approved recommendation #2).
Current codebase
indexer/src/cors_config.rs: whenINDEXER_PRODUCTIONis unset/false, the API usesCorsLayer::permissive()— any browser origin can read responses.INDEXER_PRODUCTION=1/true/yes, startup requires non-emptyCORS_ALLOWED_ORIGINS(comma-separated exact origins).indexer/src/config.rs: production mode already fail-closes on placeholderDATABASE_URLsubstrings (#142) and invalidADDRESS_REGISTRY(#156).LISTEN_ADDRis127.0.0.1:3100; operators can bind0.0.0.0for public exposure.indexer/README.mddocumentsINDEXER_PRODUCTIONrules but lacks a single internet-facing deploy checklist tying CORS, bind address, and production flag together.indexer/.env.examplementions production CORS but does not warn about public bind without production mode.Why needed
An operator who exposes the indexer on a public URL without
INDEXER_PRODUCTION=1enables permissive CORS. That does not bypass onchain auth (API is read-only) but increases phishing/social-engineering surface: third-party sites can embed live arena and wallet-scoped public stats in deceptive UIs.Parent #325 approved mandatory production configuration for any internet-facing indexer URL.
Constraints / guardrails
scripts/start-local-anvil-stack.shmust continue to work withpostgres://yieldomega:password@…and permissive CORS whenINDEXER_PRODUCTIONis omitted.INV-INDEXER-142,INV-INDEXER-156, and CORS behavior underINDEXER_PRODUCTION=1.Relevant files
indexer/src/cors_config.rsindexer/src/config.rs,indexer/src/main.rsindexer/README.md,indexer/.env.example,docs/operations/deployment-guide.mdscripts/verify-cloud-postgres.sh,indexer/tests/integration_stage2.rsdocs/testing/invariants-and-business-logic.mdRecommended direction
INDEXER_PRODUCTION=1CORS_ALLOWED_ORIGINSto production frontend origin(s) onlyDATABASE_URLand validatedADDRESS_REGISTRYdocs/operations/deployment-guide.mdindexer sectionlisten_addris not loopback (127.0.0.1/::1) andINDEXER_PRODUCTIONis false, emit a high-visibilitytracing::warn!(or exit non-zero if team agrees) naming F-04 and pointing to the checklist..env.example: prominent comment that publicLISTEN_ADDRrequiresINDEXER_PRODUCTION=1+CORS_ALLOWED_ORIGINS.INV-INDEXER-325-PUBLIC-CORS) and unit test for the bind-address + production-mode check.Acceptance criteria
indexer/README.md(and cross-link from deployment guide).INDEXER_PRODUCTION.bash scripts/start-local-anvil-stack.sh) unchanged: starts with default env, permissive CORS OK on127.0.0.1.INDEXER_PRODUCTION=1+ valid CORS origins + realDATABASE_URL, startup still succeeds.Test plan
cd indexer && cargo clippy --all-targets -- -D warnings && cargo testcd indexer && cargo test --test integration_stage2(withYIELDOMEGA_PG_TEST_URLor native Postgres perAGENTS.md)bash scripts/verify-cloud-postgres.shthenbash scripts/verify-podium-live-anvil.shor stack start on:3100bash scripts/check-doc-anchors.sh(if docs touched)Attack / abuse test plan
LISTEN_ADDR=0.0.0.0:3100, noINDEXER_PRODUCTION: confirm warning appears in logs; from another origin in browser/curl, confirmAccess-Control-Allow-Origin: *behavior (documents risk).INDEXER_PRODUCTION=1+CORS_ALLOWED_ORIGINS=https://allowed.example: only allowed origin receives CORS headers on preflight.:password@inDATABASE_URL.Verification criteria
mentioned in issue #325
mentioned in merge request !499
mentioned in commit
2d0251d297Verification — GitLab #326 (PASS)
Verified Harden internet-facing indexer production checklist and CORS bind guard on
main(no repo changes; implementation already merged).Acceptance criteria
indexer/README.mdINDEXER_PRODUCTION,CORS_ALLOWED_ORIGINS,DATABASE_URL,ADDRESS_REGISTRY, bind guidancedocs/operations/deployment-guide.mdlinks to checklist anchorINDEXER_PRODUCTIONLISTEN_ADDR=0.0.0.0:3199(no production flag) → log:LISTEN_ADDR is not loopback but INDEXER_PRODUCTION is unset — API uses permissive CORS…naming F-04 and checklist linksbash scripts/verify-podium-live-anvil.sh→ OK; loopback127.0.0.1:3201bind emits no public-bind warningINDEXER_PRODUCTION=1+ CORS + non-placeholderDATABASE_URLstartupCORS_ALLOWED_ORIGINS=https://allowed.example→ indexer starts; no public-bind warning when production setpublic_bind_guard_testsinindexer/src/config.rs(loopback detection, warn skip paths)Test plan
cd indexer && cargo clippy --all-targets -- -D warningscd indexer && cargo testpublic_bind_guard_tests, CORS parse tests,INV-INDEXER-142DB URL guards)cd indexer && cargo test --test integration_stage2 -- --test-threads=1--test-threads=1if flaky)bash scripts/verify-cloud-postgres.shbash scripts/verify-podium-live-anvil.shbash scripts/check-doc-anchors.shINV-INDEXER-326-PUBLIC-BIND-CORSanchor)Attack / abuse checks
LISTEN_ADDR=0.0.0.0, noINDEXER_PRODUCTIONtracing::warn!; preflightOrigin: https://evil.example→access-control-allow-origin: *INDEXER_PRODUCTION=1,CORS_ALLOWED_ORIGINS=https://allowed.exampleaccess-control-allow-origin: https://allowed.example; disallowed origin omits allow-origin:password@inDATABASE_URLINV-INDEXER-142)Invariants
INV-INDEXER-326-PUBLIC-BIND-CORSdocumented indocs/testing/invariants-and-business-logic.mdwith cross-links towarn_public_bind_without_productionand README.INV-INDEXER-142/INV-INDEXER-156unchanged (unit tests pass).Closes recommendation #2 from parent #325 (audit F-04).
mentioned in issue #341