HIGH dns rebindingbearer tokens

Dns Rebinding with Bearer Tokens

How Dns Rebinding Manifests in Bearer Tokens

Dns Rebinding attacks exploit the trust relationship between a client and a server when both use the same domain name. In the context of Bearer Tokens, this vulnerability becomes particularly dangerous because tokens are often stored in browser storage or passed via HTTP headers, creating a perfect target for attackers.

The attack works by manipulating DNS records so that a malicious site initially resolves to the attacker's IP address, then rebinds to your API server's IP address. When a client with a stored Bearer Token visits the malicious site, the browser believes it's communicating with a trusted origin and automatically includes the token in requests.

Consider this common pattern in single-page applications:

const API_URL = 'https://api.example.com';
const token = localStorage.getItem('bearer_token');

fetch(`${API_URL}/user/profile`, {
  headers: {
    'Authorization': `Bearer ${token}`
  }
})

An attacker registers api.example.com as a subdomain on their malicious site. The victim's browser, having previously authenticated with api.example.com, automatically includes the Bearer Token when the malicious site makes requests to what it believes is the legitimate API.

Real-world exploitation often involves:

  • Cross-site request forgery (CSRF) where the token is automatically included in requests
  • WebSockets that inherit the same-origin policy, allowing token theft via WebSocket messages
  • Service workers that can intercept and forward requests containing tokens
  • Browser extensions that inject scripts into pages

The attack surface expands significantly when APIs accept Bearer Tokens from any subdomain or when CORS policies are overly permissive. A vulnerable endpoint might look like:

// VULNERABLE: Accepts tokens from any subdomain
app.get('/api/data', (req, res) => {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (token) {
    // No validation of token origin or additional auth checks
    return res.json(getSensitiveData());
  }
  res.status(401).json({ error: 'Unauthorized' });
});

This pattern fails because it trusts the presence of a Bearer Token without validating the request context or implementing additional security controls.

Bearer Tokens-Specific Detection

Detecting Dns Rebinding vulnerabilities in Bearer Token implementations requires both automated scanning and manual testing. The middleBrick scanner includes specific checks for this attack pattern by testing how your API handles requests from unexpected origins.

middleBrick's Bearer Token detection workflow includes:

  • Origin validation testing: Attempts requests from domains that could be controlled by attackers
  • CORS policy analysis: Identifies overly permissive cross-origin configurations
  • Token binding verification: Checks if tokens are properly bound to specific client contexts
  • Subdomain trust analysis: Tests if your API trusts requests from any subdomain

Manual detection should include these steps:

// Test 1: Check if tokens work across subdomains
const testSubdomain = 'malicious.api.example.com';
const token = await getValidBearerToken();

const response = await fetch(`https://${testSubdomain}/api/protected`, {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

console.log(response.status); // Should be 401 if properly secured

Additional detection methods:

  1. Monitor for unexpected token usage patterns in logs
  2. Test with tools like dnsrebind-tool to simulate attack scenarios
  3. Check if your API accepts tokens without validating client IP or user agent
  4. Verify that refresh tokens are properly bound to specific devices

middleBrick's LLM/AI Security module also scans for AI-specific vulnerabilities where LLM endpoints might accept Bearer Tokens and be vulnerable to prompt injection attacks that could exfiltrate tokens.

Bearer Tokens-Specific Remediation

Securing Bearer Tokens against Dns Rebinding requires implementing multiple defense layers. The most effective approach combines token binding, origin validation, and secure storage practices.

Token Binding Implementation:

// Bind tokens to specific client attributes
function createSecureBearerToken(userId, deviceId, userAgent) {
  const payload = {
    sub: userId,
    device: deviceId,
    ua_hash: crypto.createHash('sha256').update(userAgent).digest('hex'),
    iat: Date.now()
  };
  
  const token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1h' });
  return token;
}

// Validate token context on each request
function validateBearerTokenContext(req, tokenPayload) {
  const currentDevice = req.headers['x-device-id'];
  const currentUserAgent = req.headers['user-agent'];
  
  if (tokenPayload.device !== currentDevice) {
    throw new Error('Device mismatch');
  }
  
  const uaHash = crypto.createHash('sha256').update(currentUserAgent).digest('hex');
  if (tokenPayload.ua_hash !== uaHash) {
    throw new Error('User agent mismatch');
  }
  
  return true;
}

Origin Validation Middleware:

function originValidationMiddleware(req, res, next) {
  const origin = new URL(req.headers.origin || req.headers.referer || '').hostname;
  const expectedOrigin = new URL(process.env.API_BASE_URL).hostname;
  
  if (origin !== expectedOrigin && !isWhitelistedOrigin(origin)) {
    return res.status(403).json({ 
      error: 'Invalid origin', 
      message: 'Request origin does not match expected API origin' 
    });
  }
  
  next();
}

function isWhitelistedOrigin(origin) {
  const whitelist = [
    'api.example.com', // Production
    'staging-api.example.com' // Staging
  ];
  return whitelist.includes(origin);
}

Secure Storage Patterns:

// Use httpOnly cookies instead of localStorage for tokens
app.post('/login', async (req, res) => {
  const { username, password } = req.body;
  const user = await authenticateUser(username, password);
  
  if (user) {
    const token = createSecureBearerToken(
      user.id, 
      req.deviceId, 
      req.headers['user-agent']
    );
    
    res.cookie('bearer_token', token, {
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      path: '/api',
      expires: new Date(Date.now() + 3600000) // 1 hour
    });
    
    return res.json({ success: true });
  }
  
  res.status(401).json({ error: 'Invalid credentials' });
});

Additional Security Measures:

  • Implement IP-based restrictions for sensitive operations
  • Use refresh tokens with device binding instead of long-lived access tokens
  • Log and alert on token usage from unexpected origins
  • Implement rate limiting per device/user combination
  • Use Content Security Policy headers to prevent unauthorized script execution

middleBrick's continuous monitoring can alert you when new vulnerabilities are detected, helping you maintain security as your API evolves.

Frequently Asked Questions

How can I test if my Bearer Token implementation is vulnerable to Dns Rebinding?

Use middleBrick's free scanner to test your API endpoints, or manually test by attempting requests from subdomains you control. Check if your API accepts tokens without validating the request origin or binding tokens to specific client contexts. Look for overly permissive CORS policies and ensure your tokens aren't stored in localStorage where they can be accessed by malicious scripts.

What's the difference between httpOnly cookies and Bearer Tokens in localStorage for preventing Dns Rebinding?

httpOnly cookies are significantly more secure because they cannot be accessed by JavaScript, preventing malicious scripts from reading or including them in requests. Bearer Tokens in localStorage are vulnerable to XSS attacks and can be automatically included in requests from any origin. For maximum security against Dns Rebinding, use httpOnly cookies with proper SameSite and Secure flags, combined with token binding to specific devices and user agents.