@aikidosec/firewall
Version:
Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks
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;
}