Railway
Exposed API Keys

Exposed API Keys on Railway

Railway provides a streamlined deployment experience with built-in environment variable management and service linking. However, developers frequently expose secrets by misconfiguring which variables are available to frontend builds versus backend services.

Scan Your Railway App

How It Happens

Railway makes all environment variables available to the build process and runtime. For backend services (Node.js APIs, Python servers), this works perfectly because the code runs only on the server. But when Railway hosts a frontend build (React, Vue, Next.js), the build process can embed environment variables into the client-side JavaScript bundle. Railway's service linking feature automatically injects connection strings like DATABASE_URL and REDIS_URL into linked services. If a frontend service is accidentally linked to a database, the connection string becomes available during the build. A framework like Vite that bundles VITE_ prefixed variables could embed this connection string in the client bundle. Railway templates and starter projects sometimes use shared environment variable groups that include both public and secret values. When developers fork these templates, they inherit the variable group without understanding which values are safe for frontend exposure.

Impact

Database connection strings exposed through a Railway frontend build give attackers direct SQL or NoSQL access to production data. Railway-managed PostgreSQL and Redis credentials provide full read/write access to the database, bypassing all application-level security. Exposed API keys for third-party services result in financial loss (AI API abuse) or data exposure (email service keys, payment processor keys). Railway projects often use multiple integrated services, so a single misconfiguration can expose keys for several services simultaneously. Railway's automatic deployments mean that an exposed secret goes live immediately. There is no manual deployment gate, so the window between misconfiguration and exposure is zero.

How to Detect

Open your Railway-deployed frontend in a browser and search the JavaScript bundles for database connection strings (postgres://, mongodb://, redis://), API key patterns (sk-, key-), and any long random strings that look like secrets. Review your Railway project's environment variable configuration. Check which variables are set on frontend services versus backend services. Pay special attention to Railway's auto-injected variables like DATABASE_URL on frontend services. Vibe App Scanner detects exposed credentials in deployed applications by analyzing JavaScript bundles and HTML source for known secret patterns and high-entropy strings.

How to Fix

Separate frontend and backend into distinct Railway services with their own environment variables. The frontend service should only have variables that are safe to expose (public API keys, analytics IDs). All secret keys should exist only on backend services. Remove database and service links from frontend services. Frontend services should call your backend API, which holds the database connection. The frontend should never have direct database access. For Next.js on Railway, ensure NEXT_PUBLIC_ prefixed variables contain only public values. For Vite, audit VITE_ prefixed variables. For Create React App, audit REACT_APP_ prefixed variables. Use Railway's variable reference feature (${{service.variable}}) carefully. Only reference variables from other services when the consuming service is a backend, never a frontend build.

Code Examples

Railway service architecture

Vulnerable
# Single Railway service with all variables
# railway.toml (or environment settings)
# Frontend AND backend share variables:
# DATABASE_URL=postgres://user:pass@host/db
# OPENAI_API_KEY=sk-proj-abc123
# NEXT_PUBLIC_API_URL=https://api.example.com
# All variables available during frontend build!
Secure
# Separate Railway services:

# Backend service variables:
# DATABASE_URL=postgres://user:pass@host/db
# OPENAI_API_KEY=sk-proj-abc123

# Frontend service variables (only public values):
# NEXT_PUBLIC_API_URL=https://api.example.com
# NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... (safe to expose)

Frequently Asked Questions

Does Railway protect environment variables from being exposed?

Railway stores environment variables securely and they are not visible in the UI to unauthorized users. However, Railway makes all variables available to the build process. If the build produces client-side JavaScript, any referenced variable is embedded in the bundle.

How does Railway's service linking affect secret exposure?

Service linking automatically injects connection strings (DATABASE_URL, REDIS_URL) into the linked service. If you accidentally link a database to a frontend service, the connection string becomes available during the frontend build, where it could be embedded in client-side code.

Should I use Railway's shared variable groups for frontend services?

Only if the shared group contains exclusively public values. Never share a variable group that includes database credentials or secret API keys with a frontend service. Create separate variable groups for frontend and backend services.

Is Your App Vulnerable?

VAS automatically scans for exposed api keys and other security issues in Railway apps. Get actionable results with step-by-step fixes.

Scans from $5, results in minutes.