File size: 2,689 Bytes
a5d718a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hostHeaderValidation = hostHeaderValidation;
exports.localhostHostValidation = localhostHostValidation;
/**
* Express middleware for DNS rebinding protection.
* Validates Host header hostname (port-agnostic) against an allowed list.
*
* This is particularly important for servers without authorization or HTTPS,
* such as localhost servers or development servers. DNS rebinding attacks can
* bypass same-origin policy by manipulating DNS to point a domain to a
* localhost address, allowing malicious websites to access your local server.
*
* @param allowedHostnames - List of allowed hostnames (without ports).
* For IPv6, provide the address with brackets (e.g., '[::1]').
* @returns Express middleware function
*
* @example
* ```typescript
* const middleware = hostHeaderValidation(['localhost', '127.0.0.1', '[::1]']);
* app.use(middleware);
* ```
*/
function hostHeaderValidation(allowedHostnames) {
return (req, res, next) => {
const hostHeader = req.headers.host;
if (!hostHeader) {
res.status(403).json({
jsonrpc: '2.0',
error: {
code: -32000,
message: 'Missing Host header'
},
id: null
});
return;
}
// Use URL API to parse hostname (handles IPv4, IPv6, and regular hostnames)
let hostname;
try {
hostname = new URL(`http://${hostHeader}`).hostname;
}
catch {
res.status(403).json({
jsonrpc: '2.0',
error: {
code: -32000,
message: `Invalid Host header: ${hostHeader}`
},
id: null
});
return;
}
if (!allowedHostnames.includes(hostname)) {
res.status(403).json({
jsonrpc: '2.0',
error: {
code: -32000,
message: `Invalid Host: ${hostname}`
},
id: null
});
return;
}
next();
};
}
/**
* Convenience middleware for localhost DNS rebinding protection.
* Allows only localhost, 127.0.0.1, and [::1] (IPv6 localhost) hostnames.
*
* @example
* ```typescript
* app.use(localhostHostValidation());
* ```
*/
function localhostHostValidation() {
return hostHeaderValidation(['localhost', '127.0.0.1', '[::1]']);
}
//# sourceMappingURL=hostHeaderValidation.js.map |