Arp Spoofing with Openid Connect
How Arp Spoofing Manifests in Openid Connect
Arp Spoofing in OpenID Connect environments creates unique attack vectors that exploit the protocol's reliance on HTTP redirects and token exchanges. The most common manifestation occurs during the authorization code flow, where an attacker positioned on the local network can intercept traffic between the client application and the OpenID Provider (OP).
Consider a typical OpenID Connect authorization code flow:
const authorizationUrl = new URL('https://openid-provider.com/auth');
authorizationUrl.searchParams.set('response_type', 'code');
authorizationUrl.searchParams.set('client_id', CLIENT_ID);
authorizationUrl.searchParams.set('redirect_uri', REDIRECT_URI);
authorizationUrl.searchParams.set('scope', 'openid profile email');
authorizationUrl.searchParams.set('state', generateState());
authorizationUrl.searchParams.set('nonce', generateNonce());When an attacker performs ARP spoofing on the network, they can intercept the authorization request before it reaches the OP. The attacker can then redirect the user to a malicious authorization endpoint that mimics the legitimate provider. This allows the attacker to capture the authorization code and subsequently exchange it for tokens.
The token exchange phase is particularly vulnerable. A typical token request looks like:
const tokenResponse = await fetch('https://openid-provider.com/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + btoa(CLIENT_ID + ':' + CLIENT_SECRET)
},
body: new URLSearchParams({
'grant_type': 'authorization_code',
'code': authorizationCode,
'redirect_uri': REDIRECT_URI
})
});An ARP spoofing attacker positioned between the client and OP can intercept this request, capture the authorization code, and use it to obtain valid tokens. The intercepted tokens can then be used to access protected resources, potentially including sensitive user data.
Another OpenID Connect-specific attack involves the discovery endpoint. OpenID Connect implementations typically use the discovery document at /.well-known/openid-configuration to find provider endpoints. An ARP spoofing attacker can serve a malicious discovery document that redirects clients to their own endpoints:
{
"issuer": "https://malicious-op.com",
"authorization_endpoint": "https://malicious-op.com/auth",
"token_endpoint": "https://malicious-op.com/token",
"userinfo_endpoint": "https://malicious-op.com/userinfo",
"jwks_uri": "https://malicious-op.com/jwks.json"
}Once clients are configured to use these malicious endpoints, the attacker can harvest credentials and tokens throughout the authentication process.
OpenID Connect-Specific Detection
Detecting ARP spoofing in OpenID Connect environments requires monitoring both network traffic patterns and protocol-specific anomalies. Network-level detection involves monitoring for unusual ARP traffic patterns, such as multiple MAC addresses claiming the same IP address or rapid ARP reply flooding.
For OpenID Connect-specific detection, implement monitoring of the discovery endpoint responses. Compare the received discovery document against known-good configurations:
async function validateDiscoveryDocument(discoveryUrl, expectedEndpoints) {
const response = await fetch(discoveryUrl);
const discovery = await response.json();
const violations = [];
if (discovery.issuer !== expectedEndpoints.issuer) {
violations.push(`Unexpected issuer: ${discovery.issuer}`);
}
if (discovery.authorization_endpoint !== expectedEndpoints.authorizationEndpoint) {
violations.push(`Unexpected authorization endpoint`);
}
if (discovery.token_endpoint !== expectedEndpoints.tokenEndpoint) {
violations.push(`Unexpected token endpoint`);
}
return violations;
}Implement certificate pinning for OpenID Connect endpoints to prevent man-in-the-middle attacks. Verify that TLS certificates match expected fingerprints:
async function verifyCertificateFingerprint(url, expectedFingerprint) {
const response = await fetch(url, { method: 'HEAD' });
const cert = response.headers.get('X-TLS-Cert');
const actualFingerprint = crypto.createHash('sha256').update(cert).digest('hex');
return actualFingerprint === expectedFingerprint;
}Monitor for unusual token exchange patterns that might indicate ARP spoofing attacks. Track the source IPs of token requests and flag anomalies:
const tokenExchangeLog = new Map();
async function logTokenExchange(clientId, ipAddress, timestamp) {
const key = `${clientId}-${ipAddress}`;
const lastExchange = tokenExchangeLog.get(key) || 0;
if (timestamp - lastExchange < 60000) { // 1 minute
console.warn(`Suspicious token exchange frequency from ${ipAddress}`);
}
tokenExchangeLog.set(key, timestamp);
}Implement runtime scanning with middleBrick to detect OpenID Connect vulnerabilities that could be exploited via ARP spoofing. middleBrick's black-box scanning approach tests the unauthenticated attack surface of your OpenID Connect endpoints, identifying issues like:
| Check Type | What It Tests | Relevance to ARP Spoofing |
|---|---|---|
| Authentication Bypass | Attempts to access protected endpoints without credentials | Identifies endpoints vulnerable to credential harvesting |
| Input Validation | Tests for injection vulnerabilities in parameters | Detects parameter manipulation opportunities |
| Property Authorization | Checks if sensitive data is exposed | Identifies data exposure risks |
| LLM/AI Security | Tests for AI-specific vulnerabilities | Detects AI-powered authentication components |
middleBrick's continuous monitoring capability (Pro plan) can scan your OpenID Connect endpoints on a configurable schedule, alerting you to new vulnerabilities that could be exploited through network-level attacks like ARP spoofing.
OpenID Connect-Specific Remediation
Remediating ARP spoofing vulnerabilities in OpenID Connect environments requires both network-level controls and protocol-specific hardening. Start with network segmentation to limit ARP spoofing opportunities. Implement VLANs to isolate authentication services from general network traffic.
For OpenID Connect-specific remediation, implement mutual TLS (mTLS) for all token exchanges. This ensures that both the client and server authenticate each other's certificates:
async function secureTokenExchange(clientId, clientSecret, authorizationCode) {
const tokenUrl = 'https://openid-provider.com/token';
const response = await fetch(tokenUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + btoa(CLIENT_ID + ':' + CLIENT_SECRET)
},
body: new URLSearchParams({
'grant_type': 'authorization_code',
'code': authorizationCode,
'redirect_uri': REDIRECT_URI
}),
// Ensure TLS verification is enabled
agent: new https.Agent({
rejectUnauthorized: true,
checkServerIdentity: (host, cert) => {
// Verify certificate matches expected fingerprint
if (cert.fingerprint256 !== EXPECTED_FINGERPRINT) {
throw new Error('Certificate fingerprint mismatch');
}
}
})
});
return await response.json();
}Implement PKCE (Proof Key for Code Exchange) in your OpenID Connect flows. PKCE adds a cryptographic challenge that prevents attackers from using intercepted authorization codes:
function generatePKCEChallenge() {
const codeVerifier = generateRandomString(128);
const codeChallenge = base64urlencode(sha256(codeVerifier));
return { codeVerifier, codeChallenge };
}
// In authorization request
authorizationUrl.searchParams.set('code_challenge', codeChallenge);
authorizationUrl.searchParams.set('code_challenge_method', 'S256');
// During token exchange
const tokenResponse = await fetch('https://openid-provider.com/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'grant_type': 'authorization_code',
'code': authorizationCode,
'redirect_uri': REDIRECT_URI,
'code_verifier': codeVerifier // Required for PKCE
})
});Implement strict CORS policies and validate the redirect_uri parameter against an allowlist. Never accept arbitrary redirect URIs:
const ALLOWED_REDIRECT_URIS = [
'https://your-app.com/callback',
'https://app.your-company.com/auth/callback'
];
function validateRedirectUri(redirectUri) {
if (!ALLOWED_REDIRECT_URIS.includes(redirectUri)) {
throw new Error('Invalid redirect URI');
}
const url = new URL(redirectUri);
if (url.protocol !== 'https:') {
throw new Error('Redirect URI must use HTTPS');
}
return true;
}Configure your OpenID Provider to use HTTP Strict Transport Security (HSTS) with a long max-age and includeSubDomains flag. This prevents protocol downgrade attacks that could be facilitated by ARP spoofing:
app.use((req, res, next) => {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
next();
});Integrate middleBrick's CLI tool into your development workflow to continuously scan your OpenID Connect endpoints for vulnerabilities. Run scans before deployment to staging environments:
# Scan your OpenID Connect provider
middlebrick scan https://openid-provider.com/.well-known/openid-configuration
# Integrate into CI/CD pipeline
npm install -g middlebrick
middlebrick scan --threshold B --fail-below B https://openid-provider.com/authFor enterprise deployments, middleBrick's Pro plan provides continuous monitoring with configurable scan schedules and alerts when security scores drop below your threshold. This helps detect when new vulnerabilities are introduced that could be exploited through ARP spoofing or other network attacks.