Insecure OAuth Configuration
What Is This Vulnerability?
Insecure OAuth configuration refers to misimplemented OAuth 2.0 flows that expose tokens, allow authorization code interception, or permit open redirects. Common mistakes include using the implicit flow for server-side apps, not validating the state parameter, accepting wildcard redirect URIs, and storing tokens insecurely in localStorage.
Why It Happens
OAuth 2.0 has multiple grant types and many security-critical parameters. Developers may choose the wrong flow for their application type, skip the state parameter for CSRF protection, configure overly broad redirect URI patterns, or store tokens in browser-accessible storage without understanding the risks.
Example Code
app.get("/auth/callback", async (req, res) => {
const { code } = req.query;
// No state parameter validation
const tokenResponse = await fetch("https://oauth.provider.com/token", {
method: "POST",
body: new URLSearchParams({
grant_type: "authorization_code",
code: code as string,
client_id: process.env.OAUTH_CLIENT_ID!,
client_secret: process.env.OAUTH_CLIENT_SECRET!,
redirect_uri: "https://example.com/auth/callback",
}),
});
const tokens = await tokenResponse.json();
// Token stored in localStorage via client
res.json(tokens);
});app.get("/auth/callback", async (req, res) => {
const { code, state } = req.query;
if (!state || state !== req.session.oauthState) {
return res.status(403).send("Invalid state parameter");
}
delete req.session.oauthState;
const tokenResponse = await fetch("https://oauth.provider.com/token", {
method: "POST",
body: new URLSearchParams({
grant_type: "authorization_code",
code: code as string,
client_id: process.env.OAUTH_CLIENT_ID!,
client_secret: process.env.OAUTH_CLIENT_SECRET!,
redirect_uri: "https://example.com/auth/callback",
}),
});
const tokens = await tokenResponse.json();
req.session.accessToken = tokens.access_token;
res.redirect("/dashboard");
});How Hackers Exploit It
Without state parameter validation, attackers perform CSRF attacks by tricking users into completing an OAuth flow that links the attacker's account. With overly broad redirect URIs, attackers redirect the authorization code to their own server. If tokens are stored in localStorage, any XSS vulnerability in the application gives the attacker full access to the user's OAuth tokens.
How to Fix It
Always validate the state parameter to prevent CSRF during OAuth flows. Use the authorization code flow with PKCE instead of the implicit flow. Register exact redirect URIs without wildcards. Store tokens in server-side sessions or HttpOnly cookies, never in localStorage. Validate the id_token signature and claims when using OpenID Connect.