agentggagentgg
Back to all findings
MEDIUMconfirmedweak-password-resetsecurity-question-enumeration1d6cb0f56b6b

Security question lookup by email exposed to anonymous callers

The frontend service fetches a user's security question text by email with no authentication, enabling attackers to shop accounts for guessable answers used in the password reset flow.

Filefrontend/src/app/Services/security-question.service.ts
Lines2429
Confidence
70%
File statusvalidated
Details

The findBy(email) method issues an unauthenticated GET to /rest/user/security-question?email=<email> and returns response.question. This client-side wiring confirms the backend exposes the security-question text to any anonymous caller who supplies an email address. Combined with Juice Shop's known security-question-based reset flow, an attacker can:

  1. Enumerate or guess email addresses.
  2. Retrieve the security question for each.
  3. Pick targets whose questions are trivially researchable (e.g., "Name of your favorite pet?", "Eldest sibling's middle name?").
  4. Submit the guessed answer to the reset endpoint to take over the account.
findBy (email: string) {
  return this.http.get(this.hostServer + '/' + 'rest/user/security-question?email=' + email).pipe(
    map((response: any) => response.question),
    ...
  )
}

This matches the brief's "Security-question metadata exposed" anti-pattern: endpoints that return the security question text to anonymous callers let attackers shop accounts to find easy questions. Security questions should never be a sole reset factor, and their text should not be disclosed pre-auth.

Proof of concept
  1. Open a browser/curl with no session.
  2. GET https://<host>/rest/user/security-question?email=victim@example.com
  3. Response includes the security question text (e.g., "Eldest sibling's middle name?").
  4. Research victim's social media; submit guessed answer to the reset endpoint to set a new password.
Impact

Any unauthenticated attacker who knows or guesses a user's email can retrieve that user's security question, dramatically lowering the cost of account takeover via the reset flow. Affects every registered user whose question/answer is researchable.

Validation
confirmed

The findBy(email) method in security-question.service.ts issues a plain HttpClient.get to /rest/user/security-question?email=<email> with no auth options and maps response.question from the body — this matches the known Juice Shop backend route that returns the security question text for any email without requiring a session, enabling pre-auth question enumeration that feeds the reset flow. The PoC (anonymous GET with ?email=victim@example.com returning the question text) is reachable because no auth header is set here and Juice Shop's interceptor only attaches a token if one exists. The exploit chain (enumerate emails → fetch question → guess answer → reset password) is plausible against the documented reset endpoint.

CVSS 3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Base score: 5.3 · MEDIUM

The findBy(email) method issues an unauthenticated GET to /rest/user/security-question?email=<email> with no session/token attached, so any remote anonymous caller can retrieve the question text (AV:N, AC:L, PR:N, UI:N). The disclosure is limited to the security question string for an arbitrary email — sensitive metadata that aids account takeover, but not direct credential or bulk PII exfiltration — so Confidentiality is L. This endpoint itself only reads data; the integrity-impacting reset flow lives in a separate endpoint not shown here, so I and A are N at this sink, and the scope stays within the same web application (S:U).

References