Better Auth Passkey Plugin, IDOR, CVE-2025-XXXX (High)

Listen to this Post

How the mentioned CVE works:

The vulnerability is an Insecure Direct Object Reference (IDOR) in the Better Auth Passkey Plugin. The endpoint `POST /passkey/delete-passkey` accepts a passkey identifier (ctx.body.id) directly from the user’s request without performing proper authorization checks. This identifier is then used implicitly in the backend deletion query. In configurations where `useNumberId` is enabled, passkeys are assigned simple, sequential integer IDs. An attacker with a valid session can exploit this by enumerating these numerical IDs, sending a series of crafted requests to delete passkeys belonging to any user, potentially resulting in the deletion of all passkeys in the system and causing widespread account lockouts.
Platform: ……. Better Auth Passkey Plugin
Version: …….. Affected versions
Vulnerability :…… IDOR
Severity: ……. High
date: ………. 2024-11-24

Prediction: 2024-12-08

What Undercode Say:

curl -X POST 'https://target.com/passkey/delete-passkey' \
-H 'Authorization: Bearer <VALID_SESSION_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{"id": 1}'
// Example vulnerable route handler using the ID directly
app.post('/passkey/delete-passkey', (ctx) => {
const id = ctx.body.id; // ID is taken from user input without checks
db.query('DELETE FROM passkeys WHERE id = ?', [bash]); // Direct use in query
});

How Exploit:

1. Attacker obtains a valid session token.

  1. Attacker enumerates sequential passkey IDs (e.g., 1, 2, 3…).
  2. For each ID, attacker sends a POST request to `/passkey/delete-passkey` with the ID.

4. Server deletes the passkey without verifying ownership.

Protection from this CVE:

Implement proper authorization checks. Verify the currently authenticated user owns the passkey ID before performing any deletion.

// Corrected authorization check
app.post('/passkey/delete-passkey', (ctx) => {
const userId = getCurrentUserId(ctx);
const passkeyId = ctx.body.id;
// First, verify ownership
const passkey = db.query('SELECT FROM passkeys WHERE id = ? AND user_id = ?', [passkeyId, userId]);
if (!passkey) {
throw new Error('Unauthorized');
}
db.query('DELETE FROM passkeys WHERE id = ?', [bash]);
});

Impact:

Widespread passkey deletion, account lockout, denial-of-service for users.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top