Api Key Exposure in Grape with Saml
Api Key Exposure in Grape with Saml — how this specific combination creates or exposes the vulnerability
Grape is a REST-like API micro-framework for Ruby, commonly used to build JSON APIs. When Grape endpoints are protected using SAML-based authentication, developers may inadvertently expose API keys through misconfigured endpoints, debug routes, or overly permissive CORS and session handling.
In a typical setup, a Grape API might use a SAML identity provider (IdP) to validate users via SAML assertions. If the API also exposes an endpoint that returns sensitive configuration or tokens—such as an unguarded /keys or /config route—and does not enforce proper authentication for that route, an authenticated user with a valid SAML session may be able to retrieve an API key that should remain server-side.
This exposure is particularly risky when Grape apps rely on SAML for user identity but fail to apply the same authorization checks to all routes. For example, an endpoint like GET /api/v1/internal/key might be intended for internal services only, but if it lacks a strong authentication and authorization filter, a user authenticated via SAML could read the key. The risk is compounded when Grape apps are used in microservice architectures where service-to-service calls rely on static API keys stored in environment variables; a leaked key can lead to unauthorized access across services.
Additionally, if Grape applications expose debug or error pages that include environment variables or stack traces, they may inadvertently leak API keys embedded in configuration. SAML integration does not inherently protect these endpoints; developers must explicitly secure them. A common misconfiguration is allowing unauthenticated access to routes that return sensitive metadata, especially in development mode left enabled in production.
Another vector involves the improper handling of SAML session cookies combined with API key usage. If a Grape app uses cookie-based SAML sessions but also accepts API keys via headers, an attacker who steals a session cookie might leverage it to call key-revealing endpoints. The lack of binding between the SAML identity and the API key usage context increases the chance of unauthorized access.
middleBrick detects such risks during unauthenticated scans by identifying endpoints that return sensitive data without adequate authentication, even when SAML is in use. The scanner flags these as high-severity findings and provides remediation guidance to ensure that all routes—especially those in Grape apps using SAML—are properly protected.
Saml-Specific Remediation in Grape — concrete code fixes
To prevent API key exposure in Grape when using SAML, apply explicit authentication and authorization to all endpoints, and avoid exposing sensitive data through public routes. Below are concrete code examples demonstrating secure practices.
1. Enforce SAML Authentication on All Grape Endpoints
Ensure every Grape API class includes a before filter that validates the SAML session. Do not rely on route-level guards alone.
class BaseAPI < Grape::API
before { authenticated? || error!('Unauthorized', 401) }
helpers do
def authenticated?
# Assuming SAML session is stored in env['warden'].user
!!env['warden']&.user
end
end
end
2. Remove or Protect Internal Endpoints
Do not expose internal endpoints that return API keys or configuration. If such endpoints are necessary for operations, restrict them to internal networks or require additional authentication.
class InternalAPI < Grape::API
before { authenticated? || error!('Unauthorized', 401) }
before { admin_only || error!('Forbidden', 403) }
helpers do
def admin_only
env['warden'].user.admin? || false
end
end
get '/keys' do
{ api_key: ENV['INTERNAL_API_KEY'] }
end
end
3. Use Environment Variables Securely
Never log or serialize environment variables that contain API keys. Configure Grape to filter sensitive parameters in logs.
class SecureAPI < Grape::API
format :json
# Filter sensitive params in logs
configure do |config|
config.filter_parameters += [:api_key, :secret]
end
end
4. Validate SAML Attributes for Authorization
After SAML authentication, validate user attributes before granting access to sensitive endpoints.
class UserAPI < Grape::API
before { authenticated? || error!('Unauthorized', 401) }
get '/profile' do
user = env['warden'].user
{ id: user.id, email: user.email }
end
end
5. Disable Debug Routes in Production
Ensure debug or introspection routes are not accessible in production environments.
class AppAPI < Grape::API
if ENV['RACK_ENV'] == 'production'
before { error!('Not Found', 404) }
end
get '/debug' do
{ env: ENV.to_hash }
end
end