UNPKG

@aikidosec/firewall

Version:

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

52 lines (51 loc) 2.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.looksLikeASecret = looksLikeASecret; const getFileExtension_1 = require("./getFileExtension"); const LOWERCASE = "abcdefghijklmnopqrstuvwxyz".split(""); const UPPERCASE = LOWERCASE.map((char) => char.toUpperCase()); const NUMBERS = "0123456789".split(""); const SPECIAL = "!#$%^&*|;:<>".split(""); const KNOWN_WORD_SEPARATORS = ["-"]; const WHITE_SPACE = /\s+/; const MINIMUM_LENGTH = 10; function looksLikeASecret(str) { if (str.length <= MINIMUM_LENGTH) { return false; } const hasNumber = NUMBERS.some((char) => str.includes(char)); if (!hasNumber) { return false; } const hasLower = LOWERCASE.some((char) => str.includes(char)); const hasUpper = UPPERCASE.some((char) => str.includes(char)); const hasSpecial = SPECIAL.some((char) => str.includes(char)); const charsets = [hasLower, hasUpper, hasSpecial]; // If the string doesn't have at least 2 different charsets, it's not a secret if (charsets.filter((charset) => charset).length < 2) { return false; } // If the string has white space, it's not a secret if (WHITE_SPACE.test(str)) { return false; } if (KNOWN_WORD_SEPARATORS.some((separator) => str.includes(separator))) { return false; } // Ignore static assests with random file names, e.g. index.BRaz9DSe.css" // The function shouldDiscoverRoutes already checks for this, but it's executed after this function, so the route would already be /asset/:secret const extension = (0, getFileExtension_1.getFileExtension)(str); if (extension && extension.length > 1 && extension.length < 6) { return false; } // Check uniqueness of characters in a window of 10 characters const windowSize = MINIMUM_LENGTH; const ratios = []; for (let i = 0; i <= str.length - windowSize; i++) { const window = str.slice(i, i + windowSize); const uniqueChars = new Set(window); ratios.push(uniqueChars.size / windowSize); } const averageRatio = ratios.reduce((sum, ratio) => sum + ratio, 0) / ratios.length; return averageRatio > 0.75; }