HIGH cors wildcardgrapemutual tls

Cors Wildcard in Grape with Mutual Tls

Cors Wildcard in Grape with Mutual Tls — how this specific combination creates or exposes the vulnerability

A CORS wildcard (origins: '*') in a Grape API combined with Mutual TLS (client certificate verification) can produce a misleading security posture. Individually, each control appears strong: the server requires a valid client certificate, and the API restricts origins. However, the wildcard origin allows any browser-based JavaScript origin to make requests, which can undermine the intended isolation when certificates are used for authorization rather than strict network boundary enforcement.

In practice, browsers enforce CORS in the context of the requesting origin. If a frontend hosted on https://example.com presents a valid client certificate (e.g., via a corporate-managed browser or a user-installed root CA), the request will succeed because CORS permits the wildcard and the TLS handshake succeeds. The critical nuance is that CORS is a browser security mechanism; it does not apply to non-browser clients (curl, Postman, custom scripts). Meanwhile, Mutual TLS operates at the transport layer and is enforced before the application layer (Grape) sees the request.

Risks emerge in these scenarios:

  • Cross-origin credential leakage: If the wildcard CORS policy is permissive and client certificates are issued broadly (e.g., to end-user devices), a malicious site could initiate authenticated requests from a user’s browser, potentially leveraging stored client certificates if they are accessible to the browser’s certificate store.
  • Misplaced trust in origin checks: Relying on CORS to restrict which origins can call backend APIs is insufficient when Mutual TLS is used for authorization. CORS headers returned by the server do not prevent non-browser clients from sending requests with valid certificates.
  • Certificate mapping confusion: Some implementations map client certificate fields (e.g., CN, email) to user roles. If CORS is open, any origin that can present a valid certificate can exploit permissive origin policies to interact with the API from a browser context, bypassing same-origin protections expected by the backend.

Crucially, middleBrick’s security checks flag this combination during scans because the runtime findings may reveal CORS responses with Access-Control-Allow-Origin: * alongside successful TLS client authentication. This does not indicate a tool failure; it highlights a configuration mismatch where CORS and Mutual TLS are not aligned in their security assumptions.

Mutual Tls-Specific Remediation in Grape — concrete code fixes

Remediation focuses on aligning CORS policy with the trust boundary established by Mutual TLS. Avoid broad origins when client certificates are used for authorization. Instead, specify exact origins and enforce certificate-to-user mapping carefully.

1) Configure CORS with explicit origins

Replace the wildcard with specific frontend origins. This ensures browser-based requests are only accepted from known, trusted sources.

require 'grape'
require 'rack/cors'

class MyAPI < Grape::API
  # CORS configuration via Rack middleware (outside Grape routes)
  # This block is typically placed in config.ru or a Rack configuration file
end

# Example: config.ru
use Rack::Cors do
  allow do
    origins 'https://app.yourcompany.com', 'https://staging.yourcompany.com'
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :delete, :options],
      expose: ['X-Rate-Limit-Limit', 'X-Rate-Limit-Remaining'],
      max_age: 600
  end
end

run MyAPI

2) Enforce Mutual TLS in Grape with certificate validation

Use the ssl directive in your Rack server (e.g., Puma) to require client certificates, and optionally validate them within Grape using the request environment.

# config.ru or Puma configuration snippet
ssl_options = {
  verify_mode: OpenSSL::SSL::VERIFY_PEER,
  cert_store: OpenSSL::X509::Store.new,
  # Provide paths to CA certificates that sign client certificates
  ca_file: '/path/to/ca-bundle.crt'
}

# In Puma config (config/puma.rb or via CLI):
# ssl_bind '0.0.0.0', '8443', ssl_options

class MyAPI < Grape::API
  before do
    client_cert = request.env['SSL_CLIENT_CERT']
    unless client_cert&.verify
      error!('Client certificate verification failed', 403)
    end

    # Optional: extract identity from certificate
    cert = OpenSSL::X509::Certificate.new(client_cert)
    # Map certificate fields to user/role, e.g., via CN or SAN
    # Avoid relying solely on subject CN for authorization without additional checks
  end

  get :secure_data do
    { message: 'Access granted with valid client certificate' }
  end
end

3) Tighten origin and certificate mapping

If you must support multiple origins, ensure each origin is explicitly listed. Avoid broad certificate issuance policies that allow any authenticated certificate to access any origin from any browser context.

# Example of strict per-origin configuration
use Rack::Cors do
  allow do
    origins 'https://app.yourcompany.com'
    resource '/api/*',
      headers: :any,
      methods: [:get],
      max_age: 600
  end
  allow do
    origins 'https://internal-dashboard.yourcompany.com'
    resource '/admin/*',
      headers: :any,
      methods: [:post, :put, :delete],
      max_age: 300
  end
end

Combine this with certificate revocation checks (e.g., CRL or OCSP) and short-lived certificates to reduce the impact of compromised credentials. middleBrick’s scans can validate that CORS headers are not overly permissive when client certificates are enforced, providing actionable feedback on misconfigurations.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Does a CORS wildcard always mean the API is insecure when Mutual TLS is used?
Not necessarily. CORS wildcard combined with Mutual TLS can be acceptable if the API is not intended for browser-based access from arbitrary origins. However, if the API serves browser clients, restrict origins to known frontends and ensure certificates are mapped to least-privilege roles to reduce risk.
Can non-browser clients bypass CORS even with a wildcard and Mutual TLS?
Yes. CORS is enforced by browsers only. Non-browser clients (e.g., curl, scripts) are not subject to CORS and will succeed if Mutual TLS validation passes. Use explicit origin policies and certificate-based authorization together, and rely on additional network or gateway-level controls for non-browser traffic.