UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks

113 lines (112 loc) 4.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkIfRequestIsBlocked = checkIfRequestIsBlocked; const Context_1 = require("../../agent/Context"); const escapeHTML_1 = require("../../helpers/escapeHTML"); const ipAllowedToAccessRoute_1 = require("./ipAllowedToAccessRoute"); const checkedBlocks = Symbol("__zen_checked_blocks__"); /** * Inspects the IP address and user agent of the request: * - Whether the IP address is blocked by an IP blocklist (e.g. Geo restrictions) * - Whether the IP address is allowed to access the current route (e.g. Admin panel) * - Whether the user agent is blocked by a user agent blocklist */ function checkIfRequestIsBlocked( // This flag is used to determine whether the request has already been checked // We use a Symbol so that we don't accidentally overwrite any other properties on the response object // and that we're the only ones that can access it res, agent) { if (res.headersSent) { // The headers have already been sent, so we can't block the request // This might happen if the server has multiple listeners return false; } const context = (0, Context_1.getContext)(); if (!context) { return false; } if (res[checkedBlocks]) { return false; } // We don't need to check again if the request has already been checked // Also ensures that the statistics are only counted once res[checkedBlocks] = true; if (!(0, ipAllowedToAccessRoute_1.ipAllowedToAccessRoute)(context, agent)) { res.statusCode = 403; res.setHeader("Content-Type", "text/plain"); let message = "Your IP address is not allowed to access this resource."; if (context.remoteAddress) { message += ` (Your IP: ${(0, escapeHTML_1.escapeHTML)(context.remoteAddress)})`; } res.end(message); return true; } const isBypassedIP = context.remoteAddress && agent.getConfig().isBypassedIP(context.remoteAddress); if (isBypassedIP) { return false; } if (context.remoteAddress && !agent.getConfig().isAllowedIPAddress(context.remoteAddress).allowed) { res.statusCode = 403; res.setHeader("Content-Type", "text/plain"); let message = "Your IP address is not allowed to access this resource."; if (context.remoteAddress) { message += ` (Your IP: ${(0, escapeHTML_1.escapeHTML)(context.remoteAddress)})`; } res.end(message); return true; } const result = context.remoteAddress ? agent.getConfig().isIPAddressBlocked(context.remoteAddress) : { blocked: false }; if (context.remoteAddress) { // Let's see if the IP occurs on one or more monitored lists and collect those keys const monitoredKeys = agent .getConfig() .getMatchingMonitoredIPListKeys(context.remoteAddress); agent.getInspectionStatistics().onIPAddressMatches(monitoredKeys); if (result.blocked) { // Let's see if the IP occurs on one or more blocked lists and collect those keys const blockedKeys = agent .getConfig() .getMatchingBlockedIPListKeys(context.remoteAddress); agent.getInspectionStatistics().onIPAddressMatches(blockedKeys); } } if (result.blocked) { res.statusCode = 403; res.setHeader("Content-Type", "text/plain"); let message = `Your IP address is blocked due to ${(0, escapeHTML_1.escapeHTML)(result.reason)}.`; if (context.remoteAddress) { message += ` (Your IP: ${(0, escapeHTML_1.escapeHTML)(context.remoteAddress)})`; } res.end(message); return true; } const userAgent = context.headers && typeof context.headers["user-agent"] === "string" ? context.headers["user-agent"] : undefined; const isUserAgentBlocked = userAgent ? agent.getConfig().isUserAgentBlocked(userAgent) : { blocked: false }; if (userAgent) { const isMonitoredUserAgent = agent .getConfig() .isMonitoredUserAgent(userAgent); if (isUserAgentBlocked.blocked || isMonitoredUserAgent) { // Find all the matching user agent keys when it's a blocked or monitored user agent const userAgentKeys = agent .getConfig() .getMatchingUserAgentKeys(userAgent); agent.getInspectionStatistics().onUserAgentMatches(userAgentKeys); } } if (isUserAgentBlocked.blocked) { res.statusCode = 403; res.setHeader("Content-Type", "text/plain"); res.end("You are not allowed to access this resource because you have been identified as a bot."); return true; } return false; }