Delegating authentication to a third party does not mean you have delegated security. The IDaaS provider is responsible for securing the password database and the OAuth server. You are responsible for securing the integration layer: how your application validates the token, how it processes lifecycle webhooks, and how it handles user metadata. When we test applications using Auth0, Clerk, or Cognito, we completely ignore the provider's infrastructure and focus entirely on how your backend incorrectly trusts the provider's data.
Unsigned webhook callbacks and Svix bypasses
Clerk, Auth0, and Stytch frequently notify your backend application about asynchronous user events (such as registration, login, profile updates, and MFA enrollment) via webhook callbacks. If your webhook endpoint executes state-changing actions (like creating a shadow database user record, granting sign-up credits, or elevating a role) without mathematically validating the webhook signature, attackers can easily spoof these events.
// VULNERABLE Webhook endpoint handler: missing signature verification
app.post("/api/webhooks/clerk", async (req, res) => {
const event = req.body;
// Flaw: The backend trusts the client payload directly without cryptographic signature checks
if (event.type === "user.created") {
await db.user.create({
data: {
id: event.data.id,
email: event.data.email_addresses[0].email_address
}
});
}
return res.status(200).send();
}); We exploit this by sending a `POST` request directly to `/api/webhooks/clerk` containing a perfectly formatted JSON payload that mimics a `user.created` event, but we substitute our own email and assign an `admin` role metadata flag. Because the backend does not check the signature, it assumes the event genuinely came from Clerk and provisions our rogue admin account.
The Fix: Implement the provider's cryptographic signature verification library perfectly. For Clerk, you must verify the Svix headers (svix-id, svix-timestamp, svix-signature) using the raw payload body before parsing the JSON:
// SECURE Webhook pattern using Svix verification
import { Webhook } from 'svix';
import bodyParser from 'body-parser';
// Must use raw body parser to preserve exact byte sequence for signature matching
app.post("/api/webhooks/clerk", bodyParser.raw({type: 'application/json'}), async (req, res) => {
const headers = req.headers;
const payload = req.body;
const wh = new Webhook(process.env.CLERK_WEBHOOK_SECRET);
try {
// Throws an error immediately if the signature does not match the payload
const evt = wh.verify(payload, headers);
// Proceed with verified event parsing safely...
} catch (err) {
return res.status(400).json({ error: "Invalid cryptographic signature" });
}
}); Cognito: Insecure authentication flows and key settings
AWS Cognito User Pools provide comprehensive authentication APIs. A critically common configuration mistake we find in Terraform deployments is enabling the ALLOW_ADMIN_USER_PASSWORD_AUTH flow on public, client-facing App Clients. This legacy flow bypasses client secrets and allows any external client to make administrator-style authentication calls directly to Cognito. This introduces massive brute-force and credential stuffing vulnerabilities.
We test Cognito by inspecting the App Client settings. Programmatic, client-facing applications (like React or React Native) must strictly use `ALLOW_USER_SRP_AUTH` (Secure Remote Password). SRP allows the client to authenticate by proving it knows the password via cryptographic challenges, without ever sending the actual plaintext password over the network wire.
Auth0: JWT claims, audience checks, and the "None" algorithm
When Auth0 returns a JWT Access Token, your backend must mathematically validate the signature using the JSON Web Key Set (JWKS) provided by Auth0 (located at https://YOUR_DOMAIN/.well-known/jwks.json). We audit your JWT verification middleware to ensure three critical checks are enforced:
- Signature Validation: The token must be signed using RS256, not HS256. We explicitly test for algorithm confusion attacks by modifying the token header to `alg: none` or altering it to use HS256 with the public key as the secret. The middleware must hard-reject these manipulated tokens.
- Issuer Validation: The issuer (
iss) claim must exactly match your specific Auth0 tenant domain. If it does not, attackers can generate a valid token from their own free Auth0 developer account and replay it against your API. - Audience Validation: The audience (
aud) must explicitly match your backend API Identifier. This prevents tokens generated for your frontend SPA from being maliciously replayed against your high-privilege backend microservices.
Exploiting Pre-SignUp and Post-Confirmation Triggers
IDaaS platforms allow you to write serverless functions (Auth0 Actions or Cognito Lambda Triggers) that execute during the authentication lifecycle. We heavily audit these triggers. If a Pre-SignUp trigger enriches a user profile by fetching data from an internal API, we attempt to inject malicious payloads into our signup name or email fields to trigger Server-Side Request Forgery (SSRF) or SQL injection within the Lambda function context.
Clerk webhook signature bypass leading to account creation
During a penetration test of a B2B SaaS application, we identified an exposed webhook route on /webhooks/clerk. The endpoint did not verify the Svix signature headers. We generated a synthetic JSON event payload containing a mock user ID and an email address under our control, and posted it to the route. The backend processed the request, trusting the unverified payload, and created an account with administrative permissions in the core database. Fix priority: critical. Remediated by implementing Clerk Webhook verification.
Integrating Auth0, Clerk, or AWS Cognito? Schedule a third-party auth security review.
Book an Identity / IDaaS AuditFrequently asked questions
Why is a leaked client ID in Cognito or Auth0 not a security breach?
Client IDs are intentionally public. They are designed to be embedded in client-side applications (like mobile or web apps) to route authentication requests to the correct tenant. The security relies entirely on token signatures, client secrets (for confidential backends), and strictly validated callback URI configurations.
How do you audit Clerk webhook configurations?
We verify if your endpoint cryptographically checks the `svix` headers (svix-id, svix-timestamp, svix-signature) using Clerk's SDK. If these checks are missing, attackers can trivially spoof user lifecycle events (like user.created or user.updated) to grant themselves admin privileges.
What is the security risk of AWS Cognito self-registration?
If self-registration is enabled without strict email/phone verification and robust CAPTCHA/WAF rules, attackers can script account creation, generating thousands of synthetic identities to access authorized API gateways or exhaust SMS budgets.
Bypassing Multi-Factor Authentication (MFA) implementations
IDaaS providers offer robust MFA solutions, but backend engineers frequently implement the verification step incorrectly. When a user logs in, Auth0 might issue a token with an `amr` (Authentication Methods Reference) claim indicating whether MFA was completed. If the backend fails to explicitly check the `amr` array for `mfa` or `otp` on highly sensitive endpoints (like money transfers or password resets), attackers can utilize phished credentials to generate a valid single-factor token and completely bypass the secondary verification requirement.
We test this by deliberately intercepting the authentication flow, dropping the MFA challenge response, and forwarding the partial-auth token directly to the backend API. If the API relies solely on the token signature and ignores the MFA claim status, the bypass is successful.
Related reading
Blog: JWT token security mistakes · OAuth & OIDC audits · API data leaks
Services: API security testing · Secure architecture review