UNPKG

@aikidosec/firewall

Version:

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

133 lines (132 loc) 5.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ServiceConfig = void 0; const IPMatcher_1 = require("../helpers/ip-matcher/IPMatcher"); const matchEndpoints_1 = require("../helpers/matchEndpoints"); const isPrivateIP_1 = require("../vulnerabilities/ssrf/isPrivateIP"); class ServiceConfig { constructor(endpoints, lastUpdatedAt, blockedUserIds, bypassedIPAddresses, receivedAnyStats, blockedIPAddresses, allowedIPAddresses) { this.lastUpdatedAt = lastUpdatedAt; this.receivedAnyStats = receivedAnyStats; this.blockedUserIds = new Map(); this.nonGraphQLEndpoints = []; this.graphqlFields = []; this.blockedIPAddresses = []; // If not empty, only ips in this list are allowed to access the service // e.g. for country allowlists this.allowedIPAddresses = []; this.setBlockedUserIds(blockedUserIds); this.setBypassedIPAddresses(bypassedIPAddresses); this.setEndpoints(endpoints); this.setBlockedIPAddresses(blockedIPAddresses); this.setAllowedIPAddresses(allowedIPAddresses); } setEndpoints(endpoints) { this.nonGraphQLEndpoints = endpoints.filter((endpoint) => !endpoint.graphql); this.graphqlFields = endpoints.filter((endpoint) => endpoint.graphql ? true : false); } getEndpoints(context) { return (0, matchEndpoints_1.matchEndpoints)(context, this.nonGraphQLEndpoints); } getGraphQLField(context, name, operationType) { const endpoints = (0, matchEndpoints_1.matchEndpoints)(context, this.graphqlFields.filter((field) => { if (!field.graphql) { return false; } return (field.graphql.name === name && field.graphql.type === operationType); })); return endpoints.length > 0 ? endpoints[0] : undefined; } setBypassedIPAddresses(ipAddresses) { if (ipAddresses.length === 0) { this.bypassedIPAddresses = undefined; return; } this.bypassedIPAddresses = new IPMatcher_1.IPMatcher(ipAddresses); } isBypassedIP(ip) { return this.bypassedIPAddresses ? this.bypassedIPAddresses.has(ip) : false; } setBlockedUserIds(blockedUserIds) { this.blockedUserIds = new Map(); blockedUserIds.forEach((userId) => { this.blockedUserIds.set(userId, userId); }); } isUserBlocked(userId) { return this.blockedUserIds.has(userId); } isIPAddressBlocked(ip) { const blocklist = this.blockedIPAddresses.find((blocklist) => blocklist.blocklist.has(ip)); if (blocklist) { return { blocked: true, reason: blocklist.description }; } return { blocked: false }; } setBlockedIPAddresses(blockedIPAddresses) { this.blockedIPAddresses = []; for (const source of blockedIPAddresses) { this.blockedIPAddresses.push({ blocklist: new IPMatcher_1.IPMatcher(source.ips), description: source.description, }); } } updateBlockedIPAddresses(blockedIPAddresses) { this.setBlockedIPAddresses(blockedIPAddresses); } updateBlockedUserAgents(blockedUserAgents) { if (!blockedUserAgents) { this.blockedUserAgentRegex = undefined; return; } this.blockedUserAgentRegex = new RegExp(blockedUserAgents, "i"); } isUserAgentBlocked(ua) { if (this.blockedUserAgentRegex) { return { blocked: this.blockedUserAgentRegex.test(ua) }; } return { blocked: false }; } setAllowedIPAddresses(ipAddresses) { this.allowedIPAddresses = []; for (const source of ipAddresses) { // Skip empty allowlists if (source.ips.length === 0) { continue; } this.allowedIPAddresses.push({ allowlist: new IPMatcher_1.IPMatcher(source.ips), description: source.description, }); } } updateAllowedIPAddresses(ipAddresses) { this.setAllowedIPAddresses(ipAddresses); } isAllowedIPAddress(ip) { if (this.allowedIPAddresses.length < 1) { return { allowed: true }; } // Always allow access from local IP addresses if ((0, isPrivateIP_1.isPrivateIP)(ip)) { return { allowed: true }; } const allowlist = this.allowedIPAddresses.find((list) => list.allowlist.has(ip)); return { allowed: !!allowlist }; } updateConfig(endpoints, lastUpdatedAt, blockedUserIds, bypassedIPAddresses, hasReceivedAnyStats) { this.setEndpoints(endpoints); this.setBlockedUserIds(blockedUserIds); this.setBypassedIPAddresses(bypassedIPAddresses); this.lastUpdatedAt = lastUpdatedAt; this.receivedAnyStats = hasReceivedAnyStats; } getLastUpdatedAt() { return this.lastUpdatedAt; } hasReceivedAnyStats() { return this.receivedAnyStats; } } exports.ServiceConfig = ServiceConfig;