/** * Security fix F4: /recover no longer leaks whether a display name exists. Previously an * unknown name returned 404 ("Kein Benutzer …") while an existing name + wrong PIN * returned 401 ("PIN ist falsch") — a response (and bcrypt-timing) oracle for account * enumeration. Now both return an identical 401. */ import { test, expect } from '../../fixtures/test'; test.describe('Auth — recover does not leak account existence (F4)', () => { test('unknown name and wrong PIN both return an identical 401', async ({ api, guest }) => { // Establish the event + a real user first (a truncate wipes the event row; the join // recreates it — otherwise recover 404s on "event not found" before name resolution). const g = await guest('RealPerson'); // Unknown display name → 401 "PIN ist falsch" (NOT a 404 revealing non-existence). const unknown = await api.recover('NoSuchPersonXYZ', '0000', { expectedStatus: [401] }); expect(unknown.status).toBe(401); expect(JSON.stringify(unknown.body)).toContain('PIN'); // A real user with a wrong PIN returns the same 401 shape. const wrongPin = g.pin === '0001' ? '0002' : '0001'; const wrong = await api.recover('RealPerson', wrongPin, { expectedStatus: [401] }); expect(wrong.status).toBe(401); expect(JSON.stringify(wrong.body)).toContain('PIN'); }); });