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: Originto prevent shared proxies from incorrectly reusing responses across different origins. - Explicitly define allowed HTTP methods and headers; avoid broad
*forAccess-Control-Allow-MethodsorAccess-Control-Allow-Headerswhen 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 ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion 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?
How can I verify my Sinatra CORS configuration is secure?
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.