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

Raw error object serialized into 500 response

The MongoDB rejection handler serializes the entire error object directly into the HTTP 500 response, leaking internal database error details to the client.

Fileroutes/updateProductReviews.ts
Lines2830
Confidence
90%
File statusvalidated
Details

In routes/updateProductReviews.ts, the .then(..., (err) => { res.status(500).json(err) }) handler passes the raw error object straight to res.json. When the underlying db.reviewsCollection.update call fails (e.g. due to a malformed _id, a MongoDB driver error, or a NoSQL injection probe), the full error structure — including the driver-level message, error code, and any embedded context (collection name, query shape, etc.) — is serialized into the response body.

}, (err: unknown) => {
  res.status(500).json(err)
})

This matches the rule's true-positive criterion: a catch/rejection handler in an HTTP route returns a response whose body is the entire error object serialized, with no sanitization or generic message substitution. There is no console.error-only path or toUserError mapping; the error is the response body.

Proof of concept

Send a request to the reviews update endpoint with an id payload that triggers a MongoDB driver error, for example:

PATCH /api/Reviews HTTP/1.1
Content-Type: application/json

{"id": {"$where": "function(){ throw new Error('probe'); }"}, "message": "x"}

The 500 response body will contain the serialized driver error (message, name, and any properties the driver attaches), revealing internal details about the data layer.

Impact

Attackers receive raw MongoDB/driver error information in 500 responses, aiding fingerprinting of the database technology, collection structure, and query semantics. This significantly accelerates reconnaissance for NoSQL injection and other backend attacks against the reviews endpoint. No authentication is required beyond what the endpoint normally enforces.

Validation
confirmed

The rejection handler at lines 28-30 is literally (err: unknown) => { res.status(500).json(err) }, which serializes the raw MongoDB driver error straight into the HTTP response with no sanitization or generic message substitution. An attacker can reach this route (PATCH /api/Reviews) and trigger driver errors via malformed req.body.id payloads, receiving internal DB error details (driver message/code/context) useful for fingerprinting and NoSQL injection reconnaissance. Scope explicitly instructs treating Juice Shop as production, so the training-app nature doesn't disqualify it.

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 endpoint is reachable over HTTP (AV:N), and the res.status(500).json(err) rejection handler in updateProductReviews.ts fires whenever the attacker can cause db.reviewsCollection.update to throw — e.g. by sending a malformed id body — with no preconditions (AC:L). The handler function only reads security.authenticatedUsers.from(req) for the success path's challenge logic and never rejects unauthenticated callers, so PR:N and UI:N. The leak discloses internal MongoDB driver error details (collection, query shape, error codes) but the attacker doesn't choose which fields are returned, so confidentiality is Low and no data is modified or denied (I:N/A:N); impact stays within the web component (S:U).

References