HIGH cors wildcardsinatrabasic auth

Cors Wildcard in Sinatra with Basic Auth

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

A CORS wildcard (Access-Control-Allow-Origin: *) in Sinatra becomes a security risk when combined with HTTP Basic Auth. Basic Auth relies on the browser not automatically sending credentials for cross-origin requests unless the origin is explicitly trusted. With a wildcard origin, any domain can make a request and read the response, but the browser will not include the Authorization header unless the server also sets Access-Control-Allow-Credentials: true. If a developer adds both a wildcard origin and allows credentials, the browser treats the wildcard as a specific origin for credentialed requests, effectively bypassing the same-origin policy for authenticated calls. This enables a site you control to read authenticated responses from the Sinatra service on behalf of a victim who is logged in.

The vulnerability is amplified when routes use non-prefixed paths like /api/* and the server responds with both Access-Control-Allow-Origin: * and Access-Control-Allow-Credentials: true. An attacker can craft a page that loads an XMLHttpRequest or fetch call to /api/users/me. Because the request includes credentials and the origin is reflected or set to *, the browser allows the response to be read, leaking the victim’s Basic Auth context, such as username and session linkage. This maps to the BOLA/IDOR and Data Exposure checks in middleBrick, which detect per-user data exposure and overly permissive CORS rules. The scan also flags missing Vary: Origin, which can cause shared caches to serve credentialed responses to unrelated origins, compounding the exposure.

Middleware or route-level configurations that dynamically set Access-Control-Allow-Origin from the Origin header without strict validation can unintentionally retain a wildcard pattern for unrecognized origins. middleBrick’s OpenAPI/Swagger spec analysis checks for insecure CORS definitions and runtime probes confirm whether authenticated endpoints are reachable cross-origin. Without explicit origin allowlisting, the combination of Basic Auth and a wildcard origin creates a pathway for unauthorized data retrieval, aligning with the OWASP API Top 10 for Broken Object Level Authorization and Improper Assets Management.

Basic Auth-Specific Remediation in Sinatra — concrete code fixes

Remediation centers on never pairing a wildcard CORS origin with credentialed requests and explicitly defining allowed origins. If you must support credentials, calculate the origin from the request and echo it back only when it is in an allowlist. Below is a secure Sinatra example that implements allowlisted origins with Basic Auth, includes Vary: Origin, and avoids exposing authenticated data to arbitrary domains.

require 'sinatra'
require 'base64'

ALLOWED_ORIGINS = ['https://trusted.example.com', 'https://app.example.com']
BASIC_USERNAME = 'apiuser'
BASIC_PASSWORD = 's3cur3P@ss!'

before do
  # Enforce Basic Auth for selected routes
  auth_type 'basic'
  halt 401, { 'Content-Type' => 'application/json' }, { error: 'Unauthorized' }.to_json unless authorized?
end

def authorized?
  @auth_provided ||= begin
    auth = request.env['HTTP_AUTHORIZATION']
    return false unless auth&.start_with?('Basic ')
    decoded = Base64.strict_decode64(auth.split(' ').last)
    user, pass = decoded.split(':', 2)
    user == BASIC_USERNAME && pass == BASIC_PASSWORD
  end
end

before do
  origin = request.env['HTTP_ORIGIN']
  if origin && ALLOWED_ORIGINS.include?(origin)
    response['Access-Control-Allow-Origin'] = origin
    response['Vary'] = 'Origin'
    response['Access-Control-Allow-Credentials'] = 'true'
    response['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
    response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
  end
end

options '*' do
  response['Access-Control-Allow-Origin'] = request.env['HTTP_ORIGIN'] if request.env['HTTP_ORIGIN'] && ALLOWED_ORIGINS.include?(request.env['HTTP_ORIGIN'])
  response['Access-Control-Allow-Credentials'] = 'true'
  response['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
  response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
  200
end

get '/api/profile' do
  content_type :json
  { username: BASIC_USERNAME, role: 'member' }.to_json
end

Key points in this configuration:

  • Do not set Access-Control-Allow-Origin: * when using Basic Auth with credentials; instead, echo a validated origin.
  • Always include Vary: Origin to prevent shared proxies from incorrectly reusing responses across different origins.
  • Explicitly define allowed HTTP methods and headers; avoid broad * for Access-Control-Allow-Methods or Access-Control-Allow-Headers when handling credentials.
  • Prefer token-based authentication (e.g., Bearer tokens) over Basic Auth for modern APIs, as it simplifies origin-specific handling and reduces risk of credential leakage in logs or URLs.

If you use the middleBrick CLI (middlebrick scan <url>) or GitHub Action, the scan will flag the insecure combination of wildcard origin and Basic Auth, providing prioritized findings and remediation guidance tied to compliance frameworks such as OWASP API Top 10 and SOC2.

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 Access-Control-Allow-Credentials: true dangerous with a wildcard Access-Control-Allow-Origin?
When Access-Control-Allow-Origin is set to * and Access-Control-Allow-Credentials is true, browsers treat the wildcard as a specific origin for credentialed requests. This allows any site that can force a user’s browser to make a request with Basic Auth headers to read the responses, leading to unauthorized data exposure.
How can I verify my Sinatra CORS configuration is secure?
Use the middleBrick CLI (middlebrick scan <url>) or GitHub Action to scan your API. The scan checks for wildcard origins combined with credentials, missing Vary headers, and over-permissive CORS headers, and it reports findings aligned with OWASP API Top 10 and SOC2.