Harden internet-facing indexer production checklist and CORS bind guard (#326) #499

Merged
PlasticDigits merged 1 commit from issue-326-public-bind-cors-guard into main 2026-06-15 01:01:05 +00:00
PlasticDigits commented 2026-06-14 22:50:39 +00:00 (Migrated from gitlab.com)

Summary

Implements GitLab #326 (parent #325 audit F-04): hardens internet-facing indexer deploy guidance and adds a startup guard when LISTEN_ADDR is non-loopback without INDEXER_PRODUCTION.

  • Operator checklist in indexer/README.md (internet-facing section) with cross-links from docs/operations/deployment-guide.md and docs/indexer/design.md.
  • Startup guard — warn_public_bind_without_production logs a high-visibility tracing::warn! naming permissive CORS risk and pointing to the checklist (INV-INDEXER-326-PUBLIC-BIND-CORS).
  • .env.example — prominent note that public LISTEN_ADDR requires production mode + CORS_ALLOWED_ORIGINS.
  • Unit tests — public_bind_guard_tests in indexer/src/config.rs.

Local Anvil stacks unchanged: default 127.0.0.1:3100 without INDEXER_PRODUCTION keeps permissive CORS; existing INV-INDEXER-142 / INV-INDEXER-156 behavior preserved.

Acceptance checklist

Criterion Command / step Result
Internet-facing checklist documented + deployment guide cross-link grep -n 'internet-facing-indexer-gitlab-326' indexer/README.md docs/operations/deployment-guide.md PASS
Warning on non-loopback bind without production LISTEN_ADDR=0.0.0.0:3100 INGESTION_ENABLED=0 … timeout 5 cargo run → log contains LISTEN_ADDR is not loopback PASS
Local Anvil stack unchanged (loopback + no production) Default LISTEN_ADDR=127.0.0.1:3100; unit tests warn_skipped_on_loopback_without_production PASS
Production mode + CORS + real DATABASE_URL guards intact INDEXER_PRODUCTION=1 + :password@ URL → config exit; cargo test cors_config production_database_url PASS
Bind-address guard unit tests cd indexer && cargo test public_bind_guard PASS
Indexer clippy + unit tests cd indexer && cargo clippy --all-targets -- -D warnings && cargo test PASS
Integration stage2 cd indexer && cargo test --test integration_stage2 PASS
Doc anchors bash scripts/check-doc-anchors.sh PASS
Native Postgres smoke bash scripts/verify-cloud-postgres.sh PASS

Third-party verification

  1. Check out branch issue-326-public-bind-cors-guard.
  2. Run cd indexer && cargo clippy --all-targets -- -D warnings && cargo test.
  3. With Postgres on :5433, run:
    cd indexer
    export DATABASE_URL='postgres://yieldomega:password@127.0.0.1:5433/yieldomega_indexer'
    export RPC_URL='http://127.0.0.1:8545' CHAIN_ID=31337 INGESTION_ENABLED=0
    export LISTEN_ADDR='0.0.0.0:3100' RUST_LOG='yieldomega_indexer=warn'
    timeout 5 cargo run -q 2>&1 | grep 'LISTEN_ADDR is not loopback'
    
    Expect one WARN line referencing F-04 / production checklist.
  4. Confirm INDEXER_PRODUCTION=1 + DATABASE_URL containing :password@ still fails at config load (INV-INDEXER-142).
  5. Read indexer/README.md#internet-facing-indexer-gitlab-326 and docs/testing/invariants-and-business-logic.md#indexer-public-bind-cors-guard-gitlab-326.

Related: #326 · parent #325

## Summary Implements GitLab #326 (parent #325 audit F-04): hardens internet-facing indexer deploy guidance and adds a startup guard when `LISTEN_ADDR` is non-loopback without `INDEXER_PRODUCTION`. - **Operator checklist** in `indexer/README.md` (internet-facing section) with cross-links from `docs/operations/deployment-guide.md` and `docs/indexer/design.md`. - **Startup guard** — `warn_public_bind_without_production` logs a high-visibility `tracing::warn!` naming permissive CORS risk and pointing to the checklist (`INV-INDEXER-326-PUBLIC-BIND-CORS`). - **`.env.example`** — prominent note that public `LISTEN_ADDR` requires production mode + `CORS_ALLOWED_ORIGINS`. - **Unit tests** — `public_bind_guard_tests` in `indexer/src/config.rs`. Local Anvil stacks unchanged: default `127.0.0.1:3100` without `INDEXER_PRODUCTION` keeps permissive CORS; existing `INV-INDEXER-142` / `INV-INDEXER-156` behavior preserved. ## Acceptance checklist | Criterion | Command / step | Result | |-----------|----------------|--------| | Internet-facing checklist documented + deployment guide cross-link | `grep -n 'internet-facing-indexer-gitlab-326' indexer/README.md docs/operations/deployment-guide.md` | PASS | | Warning on non-loopback bind without production | `LISTEN_ADDR=0.0.0.0:3100 INGESTION_ENABLED=0 … timeout 5 cargo run` → log contains `LISTEN_ADDR is not loopback` | PASS | | Local Anvil stack unchanged (loopback + no production) | Default `LISTEN_ADDR=127.0.0.1:3100`; unit tests `warn_skipped_on_loopback_without_production` | PASS | | Production mode + CORS + real DATABASE_URL guards intact | `INDEXER_PRODUCTION=1` + `:password@` URL → config exit; `cargo test cors_config production_database_url` | PASS | | Bind-address guard unit tests | `cd indexer && cargo test public_bind_guard` | PASS | | Indexer clippy + unit tests | `cd indexer && cargo clippy --all-targets -- -D warnings && cargo test` | PASS | | Integration stage2 | `cd indexer && cargo test --test integration_stage2` | PASS | | Doc anchors | `bash scripts/check-doc-anchors.sh` | PASS | | Native Postgres smoke | `bash scripts/verify-cloud-postgres.sh` | PASS | ## Third-party verification 1. Check out branch `issue-326-public-bind-cors-guard`. 2. Run `cd indexer && cargo clippy --all-targets -- -D warnings && cargo test`. 3. With Postgres on `:5433`, run: ```bash cd indexer export DATABASE_URL='postgres://yieldomega:password@127.0.0.1:5433/yieldomega_indexer' export RPC_URL='http://127.0.0.1:8545' CHAIN_ID=31337 INGESTION_ENABLED=0 export LISTEN_ADDR='0.0.0.0:3100' RUST_LOG='yieldomega_indexer=warn' timeout 5 cargo run -q 2>&1 | grep 'LISTEN_ADDR is not loopback' ``` Expect one WARN line referencing F-04 / production checklist. 4. Confirm `INDEXER_PRODUCTION=1` + `DATABASE_URL` containing `:password@` still fails at config load (INV-INDEXER-142). 5. Read `indexer/README.md#internet-facing-indexer-gitlab-326` and `docs/testing/invariants-and-business-logic.md#indexer-public-bind-cors-guard-gitlab-326`. Related: #326 · parent #325
PlasticDigits commented 2026-06-14 22:52:32 +00:00 (Migrated from gitlab.com)

Security review — MR !499

Commit reviewed: 3081af1175af635703b8cbd5cbc4a85a098a9690

Scope: Documentation and operator-checklist hardening for internet-facing indexer deploys (GitLab #326 / audit F-04); startup warn_public_bind_without_production guard in indexer/src/config.rs + main.rs; .env.example / README / deployment-guide cross-links; unit tests in public_bind_guard_tests.

Method: Diff review of all 7 changed files; traced LISTEN_ADDR parsing → warn_public_bind_without_production → cors_config::cors_layer_for_runtime(); verified no new attacker-controlled sinks (SQL, shell, SSRF, deserialization); confirmed CORS/runtime behavior unchanged for loopback local stacks and existing INDEXER_PRODUCTION fail-closed paths (INV-INDEXER-142, INV-INDEXER-156, production CORS allowlist).

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

The MR adds observability and operator guidance only. Permissive CORS when INDEXER_PRODUCTION is unset on a non-loopback bind is pre-existing runtime behavior (not introduced here); the new guard correctly warns via addr.ip().is_loopback() without weakening existing production gates. No injection, authz bypass, secret leakage, or EVM/contract surface in this change set.

Inline threads: none (no medium+ findings).

## Security review — MR !499 **Commit reviewed:** `3081af1175af635703b8cbd5cbc4a85a098a9690` **Scope:** Documentation and operator-checklist hardening for internet-facing indexer deploys (GitLab #326 / audit F-04); startup `warn_public_bind_without_production` guard in `indexer/src/config.rs` + `main.rs`; `.env.example` / README / deployment-guide cross-links; unit tests in `public_bind_guard_tests`. **Method:** Diff review of all 7 changed files; traced `LISTEN_ADDR` parsing → `warn_public_bind_without_production` → `cors_config::cors_layer_for_runtime()`; verified no new attacker-controlled sinks (SQL, shell, SSRF, deserialization); confirmed CORS/runtime behavior unchanged for loopback local stacks and existing `INDEXER_PRODUCTION` fail-closed paths (`INV-INDEXER-142`, `INV-INDEXER-156`, production CORS allowlist). **Outcome:** `FINDINGS: 0` medium+ **Security review: no medium+ findings on this diff.** The MR adds observability and operator guidance only. Permissive CORS when `INDEXER_PRODUCTION` is unset on a non-loopback bind is pre-existing runtime behavior (not introduced here); the new guard correctly warns via `addr.ip().is_loopback()` without weakening existing production gates. No injection, authz bypass, secret leakage, or EVM/contract surface in this change set. **Inline threads:** none (no medium+ findings).
PlasticDigits (Migrated from gitlab.com) merged commit 2d0251d297 into main 2026-06-15 01:01:05 +00:00
PlasticDigits commented 2026-06-15 01:01:12 +00:00 (Migrated from gitlab.com)

mentioned in commit 2d0251d297

mentioned in commit 2d0251d297ea0fc79d8bc52b408b0accdb675580
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega!499
No description provided.