Skip to content

Browser runtime seeds server-side secrets from import.meta.env into client-readable config #3704

Description

@tg12

Summary

The browser runtime seeds feature secrets from import.meta.env into client-readable runtime state, and the premium fetch path then consumes WORLDMONITOR_API_KEY from that client-side snapshot to authorize requests. This turns server-side key material into browser-held credential state.

Evidence

  • src/services/runtime-config.ts#L373-L412 reads every required runtime secret from environment variables in non-desktop builds and exposes them through getRuntimeConfigSnapshot().
  • src/services/premium-fetch.ts#L126-L135 reads WORLDMONITOR_API_KEY from that runtime snapshot and sends it in X-WorldMonitor-Key on browser requests.
  • RuntimeSecretKey includes multiple provider credentials and platform keys in the same browser-visible secret container.

Why this matters

  • Browser-readable runtime secrets are not secrets. Any value reachable through client code, devtools, same-origin script execution, or XSS should be treated as disclosed.
  • Using a platform key from the browser collapses the trust boundary between client and server and undermines entitlement, abuse control, and credential rotation assumptions.
  • The same mechanism creates a future footgun for any additional secret accidentally relied upon from the client snapshot.

Attack or failure scenario

A production web build is configured with WORLDMONITOR_API_KEY or other provider credentials in its environment. The client seeds those values into runtime state, and the browser request layer reuses them for premium RPC access. Any user with page access can inspect or replay the key-bearing request path, and any same-origin script bug inherits the same credential material.

Root cause

A client-side runtime-config abstraction is being used to hold values that should remain server-only, and the premium fetch path treats that client-held state as a valid auth source.

Recommended fix

  1. Remove server-side secrets from browser runtime state entirely.
  2. Restrict WORLDMONITOR_API_KEY and provider credentials to server-only code paths.
  3. Replace browser-held platform-key fallback with user/session-scoped server mediation.
  4. Add a validation guard that fails builds when non-public secret names are referenced from browser bundles.

Acceptance criteria

  • Browser bundles no longer seed non-public secrets from import.meta.env.
  • getRuntimeConfigSnapshot() does not expose credential values to client callers.
  • premiumFetch() no longer authenticates browser requests with a client-held platform key.
  • Tests or build checks fail if server-only secrets are introduced into browser runtime config.

Suggested labels

  • security
  • architecture
  • production-readiness

Severity

Critical — a platform key and other runtime secrets can cross the client/server trust boundary and become browser-accessible.

Confidence

Confirmed — the client code explicitly seeds secrets into runtime state and consumes WORLDMONITOR_API_KEY from that state for request authorization.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions