HIGH cors wildcardbasic auth

Cors Wildcard with Basic Auth

How Cors Wildcard Manifests in Basic Auth

Wildcard CORS configurations combined with Basic Authentication create a particularly dangerous attack vector that many developers overlook. When an API endpoint uses Basic Auth for authentication but has overly permissive CORS settings, attackers can exploit this combination to bypass authentication controls and access protected resources.

The core vulnerability occurs when a server responds with Access-Control-Allow-Origin: * while also requiring Basic Auth credentials. Here's why this is dangerous: the browser will automatically include Basic Auth credentials in cross-origin requests to the same origin, even though the wildcard CORS header suggests any origin should be allowed. This creates a scenario where an attacker can host a malicious page that makes authenticated requests to the target API without the user's knowledge.

Consider this common implementation pattern that's vulnerable:

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  next();
});

app.get('/api/users', authenticateBasic, (req, res) => {
  res.json(users);
});

In this setup, an attacker can create a page that makes requests to /api/users from their malicious domain. The browser automatically includes the user's Basic Auth credentials in the request, and the wildcard CORS header allows the response to be read by the attacker's page.

The attack typically follows this flow:

  1. Victim visits attacker's malicious page
  2. Page makes cross-origin request to target API with Basic Auth
  3. Browser automatically includes stored credentials
  4. Wildcard CORS allows response to be read
  5. Attacker exfiltrates sensitive data

This is particularly problematic for APIs that serve as backends for single-page applications, where Basic Auth credentials might be cached in the browser for convenience.

Basic Auth-Specific Detection

Detecting CORS wildcard issues in Basic Auth contexts requires examining both the authentication mechanism and CORS configuration together. The most effective approach is to test how the API handles cross-origin requests with Basic Auth credentials.

Using curl, you can test for this vulnerability:

curl -v -u "username:password" -H "Origin: https://evil.com" https://target.api/api/protected

Look for these indicators in the response headers:

  • Access-Control-Allow-Origin: * — The wildcard is the primary red flag
  • Access-Control-Allow-Credentials: true — This combination with * is explicitly forbidden by the CORS spec
  • Authentication success — The endpoint accepts and processes the Basic Auth credentials

For automated detection, tools like middleBrick scan APIs specifically for this combination. The scanner tests cross-origin requests with Basic Auth credentials and flags when wildcard CORS headers are returned alongside successful authentication. This black-box approach mirrors how an attacker would probe the API.

Additional detection methods include:

# Check if credentials are being sent
curl -v -u "test:test" -H "Origin: https://example.com" https://api.target/endpoint 2>&1 | grep -i "authorization"

# Test if wildcard CORS allows data exfiltration
curl -v -u "test:test" -H "Origin: https://evil.com" https://api.target/endpoint

Development teams should also audit their source code for patterns like:

// Vulnerable pattern
app.use(cors({ origin: '*', credentials: true }));

// Also vulnerable
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true');

middleBrick's scanning engine specifically identifies these Basic Auth and CORS misconfigurations, providing severity ratings and remediation guidance. The tool tests 12 security categories including authentication bypasses, making it effective at catching this specific vulnerability.

Basic Auth-Specific Remediation

Remediating CORS wildcard issues in Basic Auth contexts requires a multi-layered approach. The primary fix is to eliminate wildcard CORS headers and implement proper origin validation, but there are several complementary strategies.

The most straightforward remediation is to replace wildcard CORS with explicit origin validation:

// Node.js/Express with proper origin validation
const allowedOrigins = [
  'https://yourdomain.com',
  'https://app.yourdomain.com'
];

app.use((req, res, next) => {
  const origin = req.header('Origin');
  if (allowedOrigins.includes(origin)) {
    res.header('Access-Control-Allow-Origin', origin);
    res.header('Access-Control-Allow-Credentials', 'true');
  }
  next();
});

For Basic Auth specifically, consider these additional hardening measures:

// Use HTTPS-only cookies for Basic Auth session tokens
app.use((req, res, next) => {
  res.cookie('auth_session', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict'
  });
});

// Implement origin-based rate limiting
const originRateLimit = new Map();

function checkOriginRateLimit(req, res, next) {
  const origin = req.header('Origin') || 'unknown';
  const requests = originRateLimit.get(origin) || 0;
  
  if (requests > 100) { // Adjust based on your needs
    return res.status(429).json({ error: 'Rate limit exceeded' });
  }
  
  originRateLimit.set(origin, requests + 1);
  next();
}

Another effective approach is to implement token-based authentication instead of Basic Auth for cross-origin requests:

// Initial Basic Auth to get token
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  // Verify credentials
  const token = generateJwtToken({ sub: username });
  res.json({ token });
});

// Protected endpoint with Bearer token
app.get('/api/protected', authenticateBearer, (req, res) => {
  res.json({ data: 'Sensitive information' });
});

For APIs that must support Basic Auth, implement strict origin checking and avoid caching credentials:

// Reject requests from untrusted origins
app.use((req, res, next) => {
  const origin = req.header('Origin');
  if (origin && !isTrustedOrigin(origin)) {
    return res.status(403).json({ error: 'Untrusted origin' });
  }
  next();
});

// Don't cache Basic Auth credentials in browser
app.use((req, res, next) => {
  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
  res.setHeader('Pragma', 'no-cache');
  res.setHeader('Expires', '0');
  next();
});

middleBrick's remediation guidance specifically addresses these Basic Auth CORS combinations, providing actionable steps based on the detected configuration. The tool's findings map to OWASP API Security Top 10 categories, helping teams prioritize fixes based on severity.

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 with Access-Control-Allow-Origin: * explicitly forbidden?
The CORS specification explicitly forbids this combination because it creates a security vulnerability where credentials can be sent to any origin. When credentials are allowed, the browser requires the Access-Control-Allow-Origin header to be a specific origin, not a wildcard. This prevents attackers from reading authenticated responses from malicious pages.
Can I use wildcard CORS if I'm not using credentials?
Yes, wildcard CORS (Access-Control-Allow-Origin: *) is safe when you're not sending credentials. The vulnerability only arises when combining wildcard origins with credentialed requests (Basic Auth, cookies, or Authorization headers). For public APIs that don't require authentication, wildcard CORS is often appropriate.