Fix Shadow API Exposure in Hapi
Shadow APIs are the silent killers of your perimeter. In Hapi, these are the 'forgotten' routes—undocumented endpoints lurking in your codebase, often bypassing auth or validation. If you can't see it, you can't secure it. To fix shadow exposure, you must enforce documentation-as-code and strict schema validation.
The Vulnerable Pattern
const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 3000 });// Shadow endpoint: Undocumented, no tags, weak validation, leaks sensitive data server.route({ method: ‘GET’, path: ‘/debug/config-dump’, handler: (request, h) => { return { config: process.env }; } });
// Wildcard route that might expose internal paths server.route({ method: ‘GET’, path: ’/{any*}’, handler: (request, h) => { return ‘Catch-all active’; } });
The Secure Implementation
To eliminate Shadow APIs in Hapi, you must enforce a 'visible or dead' policy. 1. Use `hapi-swagger` to automatically generate documentation from your route configurations; any route without the 'api' tag is a red flag. 2. Implement strict Joi validation on all parameters, headers, and payloads; shadow endpoints often lack these, making them vulnerable to fuzzing. 3. Set `failAction` to 'error' to prevent silent validation bypasses. 4. Audit your codebase for legacy debug routes and wildcard handlers (`{any*}`) which are common hiding spots for undocumented functionality. If it is not in the Swagger UI, it should not be in the production binary.
const Hapi = require('@hapi/hapi'); const Joi = require('joi'); const Inert = require('@hapi/inert'); const Vision = require('@hapi/vision'); const HapiSwagger = require('hapi-swagger');const init = async () => { const server = Hapi.server({ port: 3000 });
// Register Swagger to force visibility of all routes await server.register([Inert, Vision, { plugin: HapiSwagger, options: { info: { title: 'API Documentation', version: '1.0.0' } } }]); server.route({ method: 'GET', path: '/api/v1/resource/{id}', options: { tags: ['api'], // Forces inclusion in documentation validate: { params: Joi.object({ id: Joi.number().integer().required() }), failAction: 'error' // Strict enforcement } }, handler: (request, h) => { return { status: 'secured' }; } }); await server.start();
};
Your Hapi API
might be exposed to Shadow API Exposure
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.