Cors Wildcard in Hapi with Basic Auth
Cors Wildcard in Hapi with Basic Auth — how this specific combination creates or exposes the vulnerability
A CORS wildcard (Access-Control-Allow-Origin: *) combined with HTTP Basic Authentication in a Hapi server can unintentionally expose authenticated credentials to any origin. When a route is protected by Basic Auth, the browser first sends a preflight OPTIONS request to verify cross-origin permissions. If the server responds with a wildcard origin while also requiring authentication, the browser may still include credentials in the actual request even though the wildcard suggests any origin is allowed.
This mismatch can lead to a CORS-based information leak: an attacker site can make authenticated requests on behalf of a user who has logged in, and the server may erroneously include credentials in responses allowed by the wildcard. In Hapi, this commonly occurs when the CORS policy is set globally or per-route with origin: ['*'] while authentication is enforced via a Basic Auth scheme. Even though the scheme validates credentials, the wildcard fails to restrict which origins are permitted, violating the same-origin policy principle for authenticated interactions.
For example, a Hapi server might define a route with config: { auth: 'simple' } and a CORS configuration containing origin: ['*']. In this scenario, a malicious site can trigger a cross-origin authenticated request. The browser sends the Authorization header, the server processes it, and the wildcard origin allows the response to be read by the attacker’s JavaScript. Although Basic Auth itself is not weak, the unrestricted wildcard makes the authenticated response accessible to unauthorized origins, potentially exposing session-related information or enabling unauthorized actions if the request also includes side effects.
Another subtle risk involves preflight caching. If the server supplies Access-Control-Max-Age with a long duration while using a wildcard, browsers cache the permissive CORS policy. Subsequent authenticated requests from an attacker origin can be served from cache, further extending the exposure window. This is especially critical in Hapi when routes expose sensitive data or state-changing operations under Basic Auth with a wildcard origin, as the server cannot dynamically differentiate between trusted and malicious origins at runtime.
Basic Auth-Specific Remediation in Hapi — concrete code fixes
Remediation focuses on two controls: tightening CORS origins and ensuring authentication is applied consistently. Instead of using a wildcard, explicitly list trusted origins in the CORS configuration. For routes that require authentication, avoid broad origins and ensure the CORS policy does not grant cross-origin access indiscriminately.
Below is a secure Hapi example that combines a specific origin with Basic Auth. This configuration prevents unauthorized origins from making authenticated requests while preserving functionality for known frontends.
const Hapi = require('@hapi/hapi');
const bcrypt = require('bcrypt');
const users = {
alice: await bcrypt.hash('secret123', 10)
};
const validate = async (request, username, password) => {
const stored = users[username];
if (!stored) return { isValid: false };
const isValid = await bcrypt.compare(password, stored);
return { isValid };
};
const init = async () => {
const server = Hapi.server({
port: 4000,
host: 'localhost',
routes: {
cors: {
origin: ['https://trusted.example.com'],
additionalHeaders: ['authorization', 'content-type']
}
}
});
server.auth.scheme('simple', (server) => {
return {
authenticate: (request, h) => {
const authHeader = request.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
return h.authenticated({ credentials: null, artifacts: {} });
}
const buffer = Buffer.from(authHeader.slice(6), 'base64');
const [username, password] = buffer.toString().split(':');
// validate credentials against a secure backend
return validate(request, username, password).then((result) => {
if (!result.isValid) {
return h.authenticated({ credentials: null, artifacts: {} });
}
return h.authenticated({ credentials: { username }, artifacts: {} });
});
}
};
});
server.auth.strategy('simple', 'simple');
server.route({
method: 'GET',
path: '/secure',
options: {
auth: 'simple',
handler: (request, h) => {
return { message: `Hello, ${request.auth.credentials.username}` };
},
cors: {
origin: ['https://trusted.example.com'],
additionalHeaders: ['authorization', 'content-type']
}
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
init().catch((err) => {
console.error(err);
});
If you rely on the dashboard or CLI to monitor API security, you can detect overly permissive CORS settings before they reach production. The middleBrick CLI can scan unauthenticated endpoints and flag a CORS wildcard when authentication is present, while the web dashboard lets you track these findings over time. For teams using CI/CD, the GitHub Action can enforce a maximum risk score and fail builds if a wildcard origin is detected alongside auth-required routes.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |
Frequently Asked Questions
Can a CORS wildcard be safe if Basic Auth is not used?
What is a minimal secure CORS setup for Hapi with Basic Auth?
origin: ['*'] when authentication is required. Ensure the server validates the Origin header and only echoes back trusted origins in Access-Control-Allow-Origin. Combine this with strong Basic Auth credential validation and HTTPS to protect credentials in transit.