Api Key Exposure in Rails with Session Cookies
Api Key Exposure in Rails with Session Cookies — how this specific combination creates or exposes the vulnerability
In a Rails application, storing an external API key in a session cookie can unintentionally expose the key when session handling is misconfigured. Rails’ default cookie store serializes session data into a client-side cookie, base64-encoded and optionally signed or encrypted depending on the serializer and secret key configuration. If an API key is placed directly into the session hash, it is persisted on the client and may be transmitted with every request, including logs, error reports, and browser history.
For example, assigning an API key to the session in a controller action results in the key being serialized and sent to the browser:
class SessionsController < ApplicationController
def create
user = User.find_by(email: params[:email])
if user&;.authenticate(params[:password])
session[:api_key] = params[:external_api_key]
redirect_to dashboard_path
else
redirect_to login_path, alert: 'Invalid credentials'
end
end
end
Without proper safeguards, this cookie may be transmitted over unencrypted HTTP if the application is misconfigured or lacks HSTS and secure flags, making it susceptible to network interception. Additionally, if the cookie is accessible to client-side scripts via JavaScript (e.g., missing HttpOnly), an XSS vulnerability can directly exfiltrate the API key. The risk is compounded when the API key is also logged inadvertently, such as through Rails parameter logging, which may include session contents depending on the filter parameters configuration.
Common missteps include failing to set secure: true in production, omitting httponly: true, not rotating the secret key base, and neglecting to scope the session cookie with same_site: :strict or :lax. An attacker who obtains the API key can abuse it against third-party services, leading to unauthorized access, data exfiltration, or cost exploitation, which may be detectable by the middleBrick LLM/AI Security checks for exposed credentials in outputs or unsafe consumption patterns.
middleBrick scans can surface such exposure by correlating runtime behavior with OpenAPI specifications and flagging endpoints where sensitive data like API keys might be reflected in responses or logged. While the scanner does not fix or block, its findings include remediation guidance to address insecure session handling.
Session Cookies-Specific Remediation in Rails — concrete code fixes
To mitigate API key exposure when using session cookies in Rails, enforce strict cookie attributes and avoid storing sensitive material in the session. Configure the session store with security-focused defaults in config/initializers/session_store.rb:
# config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_your_app_session',
secure: Rails.env.production?,
httponly: true,
same_site: :strict,
expire_after: 1.hour
Use secure: true in production to ensure cookies are only sent over HTTPS, httponly: true to protect against JavaScript access, and same_site: :strict or :lax to reduce cross-site request forgery risks. Avoid placing API keys or other secrets in the session; instead, store minimal identifiers and retrieve sensitive data from a server-side cache or vault.
In controllers, avoid passing raw external API keys into the session. If temporary delegation is required, use short-lived, scoped tokens stored server-side and referenced by a non-sensitive session identifier:
class ApiProxyController < ApplicationController
before_action :set_cached_token, only: [:index]
def index
response = ExternalService.call(
token: Rails.cache.read("user_token_#{current_user.id}"),
query: params[:q]
)
render json: response
end
private
def set_cached_token
token = generate_scoped_token(params[:external_api_key])
Rails.cache.write("user_token_#{current_user.id}", token, expires_in: 15.minutes)
session[:token_id] = Digest::SHA256.hexdigest(token)
end
end
Rotate your secret_key_base regularly using environment variables and ensure it is not committed to version control. Rails provides built-in generators for credentials and encrypted secrets; prefer rails credentials:edit for sensitive configuration rather than session storage. These measures reduce the likelihood of API key leakage through session cookies and align with secure development practices.
middleBrick’s scans can validate that cookie attributes and session handling conform to security best practices, and its GitHub Action integration allows you to fail builds if insecure session configurations are detected in CI/CD pipelines.