agentggagentgg
Back to all findings
CRITICALconfirmedhardcoded-secretshardcoded-hmac-secretebb5bc95b202

Hardcoded HMAC secret used for password/data signing

The HMAC-SHA256 key `pa4qacea4VK9t9nGv7yZtwmj` is hardcoded and used as the application's general-purpose HMAC secret.

Filelib/insecurity.ts
Lines4141
Confidence
98%
File statusvalidated
Details

At line 41:

export const hmac = (data: string) => crypto.createHmac('sha256', 'pa4qacea4VK9t9nGv7yZtwmj').update(data).digest('hex')

This exported hmac helper is the application's signing primitive (used elsewhere for password hashing / data integrity). Because the key is a literal in committed source code, every consumer of hmac() has a predictable, attacker-known secret — defeating the purpose of using an HMAC (an attacker can recompute any output, or precompute lookups against a small password space).

The value is clearly a real 24-character random-looking key, not a placeholder like changeme or xxx, and it is used directly in a cryptographic security context. It should be loaded from process.env or a secret manager.

Proof of concept
  1. Read the secret from line 41: pa4qacea4VK9t9nGv7yZtwmj.
  2. For any candidate password p, compute HMAC-SHA256('pa4qacea4VK9t9nGv7yZtwmj', p) and compare against stored user password hashes — this lets an attacker who has dumped the user table (e.g. via the project's well-known SQLi) trivially crack passwords without any per-user salt slowdown.
  3. Similarly, forge any value whose integrity is verified via insecurity.hmac().
Impact

Anyone with access to the source (public OSS repo) can compute valid HMACs for any input, enabling offline password recovery against leaked user tables and forgery of any data integrity-protected by hmac(). Authentication is not required to abuse the disclosure.

Validation
confirmed

Line 41 literally embeds the HMAC-SHA256 key 'pa4qacea4VK9t9nGv7yZtwmj' as a string literal inside the exported hmac helper, which the file's other code paths (and other modules importing this) use as the application's signing primitive. The scope explicitly instructs evaluating Juice Shop as a real production app, so the "intentionally vulnerable" nature doesn't downgrade the finding. Anyone with source access (it's public OSS) can recompute outputs, enabling offline password cracking against dumped hashes and forgery of any value signed via insecurity.hmac(). The unsafe element is clearly identified and the exploit path is straightforward.

CVSS 3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Base score: 9.1 · CRITICAL

The hmac helper at line 41 uses a literal key 'pa4qacea4VK9t9nGv7yZtwmj' embedded in committed source of a public OSS project, so any unauthenticated remote attacker trivially knows the secret (AV:N, AC:L, PR:N, UI:N). Because this is the application's general-purpose signing primitive (used for password hashing and data-integrity HMACs consumed via network-reachable endpoints), the attacker can forge arbitrary HMAC-signed values and offline-crack any password hashes recovered from the DB — yielding full credential disclosure (C:H) and arbitrary forgery of integrity-protected data (I:H). There is no direct availability impact (A:N), and the impact remains within the application's own security authority (S:U).

References