@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.
48 lines (47 loc) • 1.85 kB
JavaScript
;
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) {
if (typeof req.headers["x-forwarded-for"] === "string" && (0, trustProxy_1.trustProxy)()) {
const xForwardedFor = getClientIpFromXForwardedFor(req.headers["x-forwarded-for"]);
if (xForwardedFor && (0, net_1.isIP)(xForwardedFor)) {
return xForwardedFor;
}
}
}
if (req.remoteAddress && (0, net_1.isIP)(req.remoteAddress)) {
return req.remoteAddress;
}
return undefined;
}
function getClientIpFromXForwardedFor(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;
}
// 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 :
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;
}