UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Application Firewall that autonomously protects Node.js apps against common and critical attacks, provides rate limiting, detects malicious traffic (including bots), and more.

67 lines (66 loc) 2.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getIPAddressFromRequest = getIPAddressFromRequest; const net_1 = require("net"); const isPrivateIP_1 = require("../vulnerabilities/ssrf/isPrivateIP"); const trustProxy_1 = require("./trustProxy"); function getIPAddressFromRequest(req) { if (req.headers) { const ipHeaderName = getIpHeaderName(); if (typeof req.headers[ipHeaderName] === "string" && (0, trustProxy_1.trustProxy)()) { const ipHeaderValue = getClientIpFromHeader(req.headers[ipHeaderName]); if (ipHeaderValue && (0, net_1.isIP)(ipHeaderValue)) { return ipHeaderValue; } } } if (req.remoteAddress && (0, net_1.isIP)(req.remoteAddress)) { return req.remoteAddress; } return undefined; } function getIpHeaderName() { if (process.env.AIKIDO_CLIENT_IP_HEADER) { return process.env.AIKIDO_CLIENT_IP_HEADER.toLowerCase(); } return "x-forwarded-for"; } function getClientIpFromHeader(value) { const forwardedIps = value.split(",").map((e) => { const ip = e.trim(); // We do a first check here to make sure that valid IPv6 addresses don't // get split on ":" below. if ((0, net_1.isIP)(ip)) { return ip; } // Normalize IPv6 without port by removing brackets if (ip.startsWith("[") && ip.endsWith("]")) { return ip.slice(1, -1); } // According to https://www.rfc-editor.org/rfc/rfc7239 (5.2) X-Forwarded-For // is allowed to include a port number, so we check this here, first for IPv6 if (ip.startsWith("[")) { // IPv6 with port: [ip]:port const closingBracket = ip.indexOf("]:"); if (closingBracket > 0) { return ip.slice(1, closingBracket); } } // Handle IPv4 with port: ip:port if (ip.includes(":")) { const parts = ip.split(":"); if (parts.length === 2) { return parts[0]; } } return ip; }); // When selecting an address from the X-Forwarded-For header, // we should select the first valid IP address that is not a private IP address for (let i = 0; i < forwardedIps.length; i++) { if ((0, net_1.isIP)(forwardedIps[i]) && !(0, isPrivateIP_1.isPrivateIP)(forwardedIps[i])) { return forwardedIps[i]; } } return null; }