Description
Including exception details such as err.message or err.toString() directly in HTTP response bodies or headers may expose internal paths, SQL errors, configuration values, or clues about library behavior. Attackers can use this information during reconnaissance to refine later injection attempts or attacks against the environment.
Potential impact
- Internal paths, query structures, library versions, and configuration values may be disclosed.
- Attackers may use error messages to adjust subsequent attack payloads.
- Details of production error handling may reveal the service's structure.
Remediation
- Return generic error messages to clients and retain exception details only in server logs.
- Use centralized Express or Node error handling for consistent responses, without exposing
err.messagedirectly. - Keep exception details out of response bodies, JSON, and headers.
- Disable development debug responses in production.
Examples
Before
javascript
app.get("/profile", async (req, res) => {
try {
const profile = await loadProfile(req.user.id);
res.json(profile);
} catch (err) {
res.status(500).send(err.message);
}
});
After
javascript
app.get("/profile", async (req, res) => {
try {
const profile = await loadProfile(req.user.id);
res.json(profile);
} catch (err) {
logger.error({ err }, "profile load failed");
res.status(500).json({ error: "Internal server error" });
}
});
Explanation:
- Before: The exception message is included directly in the response, exposing internal error details.
- After: Details remain in server logs, while the client receives a generic message.