Fix Improper Error Handling in Hapi
Improper error handling in Hapi frameworks often leads to CWE-209: Information Exposure through an Error Message. By default, unhandled exceptions or poorly managed Boom objects can leak stack traces, internal IP addresses, and database schema details. A hardened Hapi implementation must intercept the response lifecycle to ensure that while developers get full debug logs, the attacker only sees a generic status code.
The Vulnerable Pattern
const Hapi = require('@hapi/hapi');const init = async () => { const server = Hapi.server({ port: 3000 });
server.route({ method: 'GET', path: '/user/{id}', handler: async (request, h) => { // VULNERABILITY: Raw error thrown from DB is passed directly to the client // This could leak connection strings or query logic const user = await db.query(`SELECT * FROM users WHERE id = ${request.params.id}`); return user; } }); await server.start();
}; init();
The Secure Implementation
The secure implementation utilizes Hapi's 'onPreResponse' extension point to act as a security middleware. When an error (Boom object) is detected, the code logs the full technical details to a secure internal stream but overwrites the 'message' field in the 'response.output.payload' with a non-descriptive string for any 5xx errors. This ensures the application fails safely without providing a roadmap for exploitation.
const Hapi = require('@hapi/hapi'); const Boom = require('@hapi/boom');const init = async () => { const server = Hapi.server({ port: 3000 });
// SECURE: Global error interceptor via onPreResponse server.ext('onPreResponse', (request, h) => { const response = request.response; if (!response.isBoom) { return h.continue; } // Log the actual error internally for SRE/Devs console.error('Internal Error:', response.stack || response.message); // Sanitize response: Clear sensitive data before it hits the wire const error = response.output.payload; if (response.output.statusCode >= 500) { error.message = 'An internal server error occurred'; // Generic message } return h.continue; }); server.route({ method: 'GET', path: '/user/{id}', handler: async (request, h) => { try { return await db.query('SELECT * FROM users WHERE id = ?', [request.params.id]); } catch (err) { // Wrap in Boom but the interceptor will sanitize it throw Boom.internal('Database failure'); } } }); await server.start();
}; init();
Your Hapi API
might be exposed to Improper Error Handling
74% of Hapi apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.