Skip to content

security: guard NEXT_PUBLIC_DEV_SECRET_KEY so it can never activate outside local dev #64

Description

@tech-adrian

Area
frontend/src/lib/stellar.ts, frontend/src/components/WalletProvider.tsx, frontend/.env.local.example

Problem
NEXT_PUBLIC_DEV_SECRET_KEY (stellar.ts:6) is NEXT_PUBLIC_-prefixed, meaning whenever it's set, the secret key is inlined verbatim into the shipped client JS bundle — visible to anyone via view-source/devtools. When set, WalletProvider auto-connects every visitor as that keypair with no wallet picker (localStorage.setItem("dshield_wallet", addr)), and signTransaction silently signs any transaction with it via devSignTransaction — no popup, no user confirmation, no NODE_ENV guard of any kind. This is fine and intentional for local-only demo convenience (documented in .env.local.example as "reserved strictly for local environment simulation"), but nothing enforces that boundary. A misconfigured preview/staging deployment, a copy-pasted .env file, or a shared CI secret would leak the key to the entire internet and let any visitor drain its funds and sign arbitrary transactions as it, silently.

Proposed change
Add a runtime guard so this path can't accidentally activate outside local development — e.g. only honor NEXT_PUBLIC_DEV_SECRET_KEY when process.env.NODE_ENV !== "production", and/or check window.location.hostname is localhost/127.0.0.1 before wiring up getDevKeypair()/devSignTransaction. If the guard trips (var is set somewhere it shouldn't be), fail loudly with a visible warning rather than silently using it.

Acceptance Criteria

  • NEXT_PUBLIC_DEV_SECRET_KEY path is inert in a production build (or non-localhost origin), verified by a test/build check
  • A visible warning/error is surfaced if the var is set somewhere the guard blocks it, rather than silent fallback to normal wallet flow
  • .env.local.example comment updated to reference the new guard
  • Relevant tests (just test, pnpm test, cargo test, or nargo test as applicable) pass locally and in CI
  • A screenshot or short screen recording is attached to the PR showing the change working (a production build ignoring the var even when set) — required before this can be merged.

Open your PR against the dev branch, not main. All active development merges into dev.

Discuss this issue / coordinate work: join the DShield contributor Telegram group: https://t.me/+SiGHH24No9U2MDJk

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions