HIGH cross site request forgerybasic auth

Cross Site Request Forgery with Basic Auth

How Cross Site Request Forgery Manifests in Basic Auth

Cross Site Request Forgery (CSRF) in Basic Auth environments exploits a fundamental trust relationship between browsers and servers. When a user authenticates with Basic Auth, the browser automatically includes the Authorization header with every request to that domain, creating a persistent credential that malicious sites can trigger without user awareness.

The attack sequence typically follows this pattern: A user visits a malicious site while already authenticated to a vulnerable Basic Auth API. The attacker's page includes hidden forms or JavaScript that make requests to the target API. Since Basic Auth credentials are automatically included by the browser for the authenticated domain, the API processes these requests as if they came from the legitimate user.

Consider this vulnerable pattern:

fetch('https://api.example.com/user/delete', {
  method: 'POST'
});

An attacker could host this on their site. When a logged-in user visits, their browser automatically appends the Basic Auth header, resulting in:

Authorization: Basic base64(username:password)

The server receives a valid authenticated request and processes the deletion, even though the user never intended to take this action on the attacker's site.

Common attack vectors include:

  • Hidden form submissions with auto-submitted POST requests
  • Image tags that trigger GET requests with side effects
  • XMLHttpRequest or fetch calls from malicious pages
  • Malicious links sent via email or messaging apps

The fundamental problem is that Basic Auth lacks any built-in CSRF protection mechanism. Unlike session-based authentication where you can use anti-CSRF tokens, Basic Auth provides no native way to distinguish legitimate requests from forged ones.

Basic Auth-Specific Detection

Detecting CSRF vulnerabilities in Basic Auth systems requires examining both the authentication mechanism and request patterns. middleBrick's black-box scanning approach specifically tests for these vulnerabilities by attempting to trigger state-changing operations without proper CSRF protection.

Key detection indicators include:

  • State-changing endpoints (POST, PUT, DELETE) that accept Basic Auth without additional verification
  • Missing anti-CSRF tokens in request headers or bodies
  • Endpoints that process requests from any origin without CORS restrictions
  • API responses that reveal whether authentication succeeded without additional checks

middleBrick scans for CSRF by attempting to execute privileged operations through crafted requests, then analyzing whether the server processes them as authenticated actions. The scanner tests common attack patterns including form submissions, script-based requests, and cross-origin calls.

For manual verification, developers can test using tools like curl or browser developer tools:

# Test if Basic Auth credentials are automatically included
curl -v -u username:password https://api.example.com/endpoint

# Test cross-origin behavior
curl -H "Origin: https://malicious-site.com" -u username:password https://api.example.com/endpoint

Additional detection methods include reviewing API specifications for endpoints that modify data without CSRF protection, and examining client-side code for patterns that might inadvertently expose Basic Auth credentials to third-party scripts.

Basic Auth-Specific Remediation

Remediating CSRF in Basic Auth environments requires implementing additional verification layers since Basic Auth itself provides no CSRF protection. The most effective approach combines origin validation with custom authentication headers.

Origin validation implementation:

// Server-side origin validation middleware
const allowedOrigins = ['https://yourdomain.com', 'https://yourapp.com'];

app.use((req, res, next) => {
  const origin = req.headers.origin || req.headers.referer;
  
  if (req.method === 'GET' || allowedOrigins.includes(origin)) {
    next();
  } else {
    // For state-changing requests, require additional verification
    const expectedHeader = req.headers['x-custom-auth'];
    if (expectedHeader && validateCustomAuth(expectedHeader)) {
      next();
    } else {
      res.status(403).json({ error: 'CSRF validation failed' });
    }
  }
});

Custom authentication header approach:

// Client-side: include custom header with Basic Auth
fetch('https://api.example.com/endpoint', {
  method: 'POST',
  headers: {
    'Authorization': 'Basic ' + btoa(username + ':' + password),
    'X-Custom-Auth': generateAuthToken()
  }
});

// Server-side: validate both Basic Auth and custom token
app.post('/endpoint', (req, res) => {
  const basicAuth = req.headers.authorization;
  const customAuth = req.headers['x-custom-auth'];
  
  if (!basicAuth || !customAuth) {
    return res.status(401).json({ error: 'Missing authentication' });
  }
  
  if (!validateCustomAuth(customAuth)) {
    return res.status(403).json({ error: 'Invalid custom auth token' });
  }
  
  // Process request
});

Alternative approach using double-submit cookie pattern:

// Generate random token and set as cookie
app.use((req, res, next) => {
  if (!req.cookies.csrf_token) {
    const token = crypto.randomBytes(32).toString('hex');
    res.cookie('csrf_token', token, { httpOnly: true });
  }
  next();
});

// Require token in custom header for state changes
app.post('/sensitive', (req, res) => {
  const basicAuth = req.headers.authorization;
  const csrfToken = req.headers['x-csrf-token'];
  const cookieToken = req.cookies.csrf_token;
  
  if (csrfToken !== cookieToken) {
    return res.status(403).json({ error: 'CSRF token mismatch' });
  }
  
  // Process authenticated request
});

For applications that can't modify the authentication flow, consider implementing API-level rate limiting and request signing to mitigate CSRF impact even if requests are forged.

Frequently Asked Questions

Can CSRF attacks work with Basic Auth if the user isn't actively logged in?
No, CSRF with Basic Auth requires the user to have previously authenticated and stored credentials in their browser. The browser automatically includes Basic Auth credentials for the domain, but only if they've been cached from a prior successful authentication. If the user hasn't logged in, the browser won't include credentials, and the attack fails.
Does HTTPS protect against CSRF in Basic Auth?
No, HTTPS encrypts the connection but doesn't prevent CSRF attacks. The attack exploits the browser's automatic credential inclusion behavior, which works over HTTPS just as it does over HTTP. While HTTPS prevents credential interception during transmission, it doesn't stop the browser from automatically sending cached Basic Auth credentials to the server.