hostHeaderValidation.js 2.5 KB

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