agentggagentgg
Back to all findings
MEDIUMconfirmederror-message-leakerror-message-leak343f22f6d688

Catch blocks return raw error message via utils.getErrorMessage

Both catch blocks in serveCodeSnippet and checkVulnLines return the raw error message to the client via utils.getErrorMessage(error), which extracts err.message and leaks it in the HTTP response body.

Fileroutes/vulnCodeSnippet.ts
Lines5557
Confidence
55%
File statusvalidated
Details

In serveCodeSnippet (lines 44-58) and checkVulnLines (lines 78-89), the catch blocks respond with:

res.status(statusCode).json({ status: 'error', error: utils.getErrorMessage(error) })

utils.getErrorMessage is a thin helper that returns error.message for Error instances (and String(error) otherwise) — it is not a sanitizer that maps known error classes to user-safe text. Any unexpected exception thrown by retrieveCodeSnippet / getCodeChallenges (filesystem errors, YAML parse errors, etc.) will have its underlying message echoed verbatim to the HTTP client. This matches the rule's true-positive criterion: a catch in an HTTP route handler whose response body includes the raw err.message.

Proof of concept
  1. Cause getCodeChallenges() / retrieveCodeSnippet() to throw (e.g., by corrupting or removing a backing file referenced during challenge loading so a downstream fs/yaml error is raised).
  2. Issue GET /snippet/<challengeKey> or POST to the verdict endpoint with a key that triggers the failure path.
  3. Observe the JSON response body: { "status": "error", "error": "ENOENT: no such file or directory, open '/abs/path/to/data/static/codefixes/<key>.yml'" } — the raw error message exposes filesystem paths and library internals.
Impact

Unauthenticated remote callers can probe error paths to harvest internal details (file paths, library/driver-specific error text, stack-like fragments) that aid reconnaissance and chained exploitation. No authentication is required because both handlers are reachable by any client able to reach the routes.

Validation
confirmed

Both catch blocks at lines 55–57 and 86–88 call res.status(statusCode).json({ status: 'error', error: utils.getErrorMessage(error) }), which returns error.message verbatim. Underlying calls (getCodeChallenges, fs.readFileSync via YAML loading) can raise ENOENT/YAML parse errors whose messages embed absolute filesystem paths and library internals. The routes are reachable by clients supplying a challenge param/key body field, so an attacker can probe error paths to harvest reconnaissance details. The detector's description matches the code; this is a genuine information-leak bug, albeit low severity.

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 catch blocks in serveCodeSnippet and checkVulnLines return utils.getErrorMessage(error) directly to the HTTP client without any sanitization or mapping, and neither route shows any authentication middleware, so an unauthenticated remote caller can reach them over the network (AV:N, PR:N, UI:N, AC:L). Triggering the error path (e.g., supplying a key that causes the downstream fs/yaml/getCodeChallenges call to throw) leaks fragments such as absolute filesystem paths and library-internal error text — that is partial, attacker-uncontrolled information disclosure, hence C:L. The leak does not let the attacker modify state or degrade availability (I:N, A:N), and the impact is contained within the same web component (S:U).

References