@aikidosec/firewall
Version:
Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks
54 lines (53 loc) • 2.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkContextForSSRF = checkContextForSSRF;
const Source_1 = require("../../agent/Source");
const attackPath_1 = require("../../helpers/attackPath");
const extractStringsFromUserInputCached_1 = require("../../helpers/extractStringsFromUserInputCached");
const containsPrivateIPAddress_1 = require("./containsPrivateIPAddress");
const findHostnameInUserInput_1 = require("./findHostnameInUserInput");
const getMetadataForSSRFAttack_1 = require("./getMetadataForSSRFAttack");
const isRequestToItself_1 = require("./isRequestToItself");
/**
* This function goes over all the different input types in the context and checks
* if it possibly implies SSRF, if so the function returns an InterceptorResult
*/
function checkContextForSSRF({ hostname, port, operation, context, }) {
// If the hostname is not a private IP address, we don't need to iterate over the user input
// DNS lookup calls will be inspected somewhere else
// This is just to inspect direct invocations of `http.request` and similar
// Where the hostname might be a private IP address (or localhost)
if (!(0, containsPrivateIPAddress_1.containsPrivateIPAddress)(hostname)) {
return;
}
if (context.url &&
(0, isRequestToItself_1.isRequestToItself)({
serverUrl: context.url,
outboundHostname: hostname,
outboundPort: port,
})) {
// We don't want to block outgoing requests to the same host as the server
// (often happens that we have a match on headers like `Host`, `Origin`, `Referer`, etc.)
return undefined;
}
for (const source of Source_1.SOURCES) {
const userInput = (0, extractStringsFromUserInputCached_1.extractStringsFromUserInputCached)(context, source);
if (!userInput) {
continue;
}
for (const str of userInput) {
const found = (0, findHostnameInUserInput_1.findHostnameInUserInput)(str, hostname, port);
if (found) {
const paths = (0, attackPath_1.getPathsToPayload)(str, context[source]);
return {
operation: operation,
kind: "ssrf",
source: source,
pathsToPayload: paths,
metadata: (0, getMetadataForSSRFAttack_1.getMetadataForSSRFAttack)({ hostname, port }),
payload: str,
};
}
}
}
}