HIGH cors wildcardgrapebasic auth

Cors Wildcard in Grape with Basic Auth

Cors Wildcard in Grape with Basic Auth — how this specific combination creates or exposes the vulnerability

In Grape-based APIs, combining a CORS wildcard with HTTP Basic Auth can unintentionally expose authenticated endpoints to cross-origin requests. When Access-Control-Allow-Origin is set to * while credentials or authentication headers are required, browsers may allow cross-origin requests to include credentials depending on the request mode, potentially bypassing intended origin restrictions.

For requests that include authentication (e.g., Basic Auth via the Authorization header), a wildcard origin can enable a cross-origin attacker to make authenticated requests from a malicious site if the API also reflects or trusts the Origin header improperly. While Basic Auth sends credentials with every request, the browser’s CORS preflight and response header handling determine whether the response is made available to the JavaScript frontend. If Access-Control-Allow-Credentials is set to true alongside a wildcard origin, this violates the CORS specification and can lead to unauthorized cross-origin access to authenticated resources.

Grape does not enforce CORS by default; developers add CORS support via middleware such as rack-cors. Misconfiguration commonly includes:

  • Setting origins: '*' while also allowing credentials.
  • Using a dynamic origin matcher that echoes the request Origin without strict validation.

For example, a vulnerable Grape API might include CORS configuration like this:

require 'grape'
require 'rack/cors'

class PublicAPI < Grape::API
  before do
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Credentials'] = 'true'
  end

  resource :users do
    desc 'Get current user, requires Basic Auth'
    before { authenticate! }
    get do
      { user: current_user }
    end
  end
end

use Rack::Cors do
  allow do
    origins '*'
    resource '*',
      headers: :any,
      methods: [:get, :post, :options],
      expose: ['Authorization']
  end
end

In this configuration, the combination of origins '*' and Access-Control-Allow-Credentials: true is invalid per the CORS specification. A cross-origin site can trigger authenticated requests that include the Basic Auth header, and if the API’s response exposes headers or data to the originating page, sensitive information may be leaked.

Additionally, if the API reflects the Origin header into responses or allows arbitrary origins via a dynamic check, an attacker can craft a page that issues authenticated requests to the Grape endpoint from a victim’s browser. The browser will include the Authorization header (Base64-encoded credentials) with the request, and depending on CORS settings, the attacker may read the response.

To detect this class of issue, scanners perform unauthenticated CORS preflight and simple GET checks while looking for wildcard origins alongside authentication requirements. They also inspect whether Access-Control-Allow-Credentials is present and true when origins are not explicitly restricted.

Basic Auth-Specific Remediation in Grape — concrete code fixes

Remediation focuses on tightening CORS configuration and avoiding unsafe combinations with HTTP Basic Auth. Since Basic Auth credentials are sent with every request, the origin must be explicitly restricted and credentials should only be allowed when necessary.

Use a strict list of trusted origins instead of a wildcard. If your API is only consumed by a known frontend, specify those origins explicitly. Also, avoid setting Access-Control-Allow-Credentials to true when using a wildcard origin.

The following example demonstrates a secure CORS setup for a Grape API using Basic Auth:

require 'grape'
require 'rack/cors'

class SecureAPI < Grape::API
  helpers do
    def authenticate!
      header['WWW-Authenticate'] = 'Basic realm="API"'
      throw(:halt, [401, { error: 'Unauthorized' }.to_json])
    end

    def current_user
      @current_user ||= begin
        auth = request.env['HTTP_AUTHORIZATION']
        return nil unless auth&.start_with?('Basic ')
        encoded = auth.split(' ').last
        userpass = Base64.strict_decode64(encoded)
        user, pass = userpass.split(':', 2)
        # Replace with secure credential verification
        user == 'admin' && pass == 's3cret' ? user : nil
      end
    end
  end

  before do
    authenticate! unless [OPTIONS].include?(request.request_method)
  end

  resource :users do
    desc 'Get current user, requires Basic Auth'
    before { authenticate! }
    get do
      { user: current_user }
    end
  end
end

# config/initializers/cors.rb or equivalent setup
use Rack::Cors do
  allow do
    origins 'https://app.example.com', 'https://api.example.com'
    resource '/api/*',
      headers: :any,
      methods: [:get, :post, :options],
      expose: [],
      max_age: 600
  end
end

Key remediation steps:

  • Specify exact origins in origins instead of '*'.
  • Do not set Access-Control-Allow-Credentials: true when using wildcard origins; if credentials are required, restrict origins rigorously.
  • Ensure that the CORS middleware is placed before Grape routing so that headers are applied consistently.
  • Validate the Origin header on the server side even when using a restricted list to prevent host-header-based bypasses.

For automated detection and ongoing compliance, integrate the middleBrick web dashboard or run the CLI tool (middlebrick scan <url>) to identify CORS misconfigurations. Teams using CI/CD can add the GitHub Action to fail builds if risk scores exceed thresholds, and the MCP Server can scan APIs directly from IDEs used by developers.

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

Why is setting Access-Control-Allow-Origin to * unsafe when Basic Auth is used?
Because a wildcard origin allows any website to make requests to the API. When credentials like Basic Auth headers are included, browsers may permit cross-origin authenticated requests, potentially exposing credentials to malicious sites if CORS rules are not strictly limited.
Should I remove Basic Auth if I need a public API?
If endpoints must be publicly accessible, avoid requiring authentication via headers such as Basic Auth. Use API keys or tokens with strict CORS policies, and ensure that authentication is only enforced for sensitive endpoints with tightly controlled origins.