Error handler leaks raw Postgres error messages (schema/column/UUID syntax) to clients #101

Closed
opened 2026-05-26 18:18:08 -04:00 by zgaetano · 1 comment
Owner

Fixed in 04ce096. errorHandler now classifies Postgres SQLSTATE codes (22P02, 23502, 23503, 23505, 42703, 42P01, 42601) and returns a generic message + the SQLSTATE code with the right HTTP status, never the raw err.message. 5xx responses are stable shape: {"error":"Internal Server Error","status":500}. 4xx still carry operator-authored messages. Full error always logged server-side.

Fixed in 04ce096. `errorHandler` now classifies Postgres SQLSTATE codes (22P02, 23502, 23503, 23505, 42703, 42P01, 42601) and returns a generic message + the SQLSTATE code with the right HTTP status, never the raw `err.message`. 5xx responses are stable shape: `{"error":"Internal Server Error","status":500}`. 4xx still carry operator-authored messages. Full error always logged server-side.
Author
Owner

Fix Plan — #101 Error handler leaks raw Postgres messages

Root cause: src/middleware/errors.js returns err.message verbatim. PG errors expose schema names, column names, SQL state codes, parser positions.

Fix — src/middleware/errors.js:

const PG_ERROR_MAP = {
  "22P02": { status: 400, message: "Invalid input format" },  // bad UUID
  "23505": { status: 409, message: "Resource already exists" }, // unique violation
  "23503": { status: 409, message: "Referenced resource not found" }, // FK violation
  "42703": { status: 400, message: "Invalid field" },  // undefined column
};

function errorHandler(err, req, res, next) {
  const pg = PG_ERROR_MAP[err.code];
  if (pg) return res.status(pg.status).json({ error: pg.message });

  // Unknown errors: log server-side, generic client response
  console.error("Unhandled error:", err);
  return res.status(500).json({ error: "Internal Server Error" });
}

Also fix direct err.message returns in sdk.js:138 and assets.js:586.

Files: src/middleware/errors.js, src/routes/sdk.js:138, src/routes/assets.js:586
Effort: ~1h
**Priority: P0 — security/info leak

## Fix Plan — #101 Error handler leaks raw Postgres messages **Root cause:** `src/middleware/errors.js` returns `err.message` verbatim. PG errors expose schema names, column names, SQL state codes, parser positions. **Fix — `src/middleware/errors.js`:** ```js const PG_ERROR_MAP = { "22P02": { status: 400, message: "Invalid input format" }, // bad UUID "23505": { status: 409, message: "Resource already exists" }, // unique violation "23503": { status: 409, message: "Referenced resource not found" }, // FK violation "42703": { status: 400, message: "Invalid field" }, // undefined column }; function errorHandler(err, req, res, next) { const pg = PG_ERROR_MAP[err.code]; if (pg) return res.status(pg.status).json({ error: pg.message }); // Unknown errors: log server-side, generic client response console.error("Unhandled error:", err); return res.status(500).json({ error: "Internal Server Error" }); } ``` Also fix direct `err.message` returns in `sdk.js:138` and `assets.js:586`. **Files:** `src/middleware/errors.js`, `src/routes/sdk.js:138`, `src/routes/assets.js:586` **Effort:** ~1h **Priority: P0 — security/info leak
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: WildDragonLLC/dragonflight#101
No description provided.