UNPKG

umbot

Version:

Мультиплатформенный фреймворк для создания голосовых навыков и чат-ботов с единой бизнес-логикой. Встроенная поддержка ВКонтакте, Telegram, Viber, MAX, Яндекс Алисы, Маруси и Сбера SmartApp. Архитектура на адаптерах позволяет подключать любые другие платф

76 lines (75 loc) 3.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isRegexLikelySafe = isRegexLikelySafe; const REG_DANGEROUS = /\)+\s*[+*{?]|}\s*[+*{?]/; const REG_PIPE = /\([^)]*\|[^)]*\)/; const REG_EV1 = /\([^)]*(\w)\1+[^)]*\|/; const REG_EV2 = /\([^)]*[+*{][^)]*\|/; const REG_REPEAT = /\([^)]*[+*{][^)]*\)\s*\{/; const REG_BAD = /\.\s*[+*{]/; function isRegexLikelySafe(pattern, isRegex) { try { if (!isRegex) { new RegExp(pattern); } // 1. Защита от слишком длинных шаблонов (DoS через размер) if (pattern.length > 1000) { return false; } // 2. Убираем экранированные символы из рассмотрения (упрощённо) // Для простоты будем искать только в "сыром" виде — этого достаточно для эвристик // 3. Основные ReDoS-эвристики // Вложенные квантификаторы: (a+)+, (a*)*, [a-z]+*, и т.п. // Ищем: закрывающая скобка или символ класса, за которой следует квантификатор const dangerousNested = REG_DANGEROUS.test(pattern); if (dangerousNested) { return false; } // Альтернативы с пересекающимися паттернами: (a|aa), (a|a+) // Простой признак: один терм — префикс другого // Точное определение сложно без AST, но часто такие паттерны содержат: // - `|` внутри группы + повторяющиеся символы const hasPipeInGroup = REG_PIPE.test(pattern); if (hasPipeInGroup) { // Дополнительная эвристика: есть ли повторяющиеся символы или квантификаторы? if (REG_EV1.test(pattern)) { return false; } if (REG_EV2.test(pattern)) { return false; } } // Повторяющиеся квантифицируемые группы: (a+){10,100} if (REG_REPEAT.test(pattern)) { return false; } // Квантификаторы на "жадных" конструкциях без якорей — сложнее ловить, // но если есть .*+ — это почти всегда опасно if (REG_BAD.test(pattern)) { return false; } // Слишком глубокая вложенность скобок — признак сложности let depth = 0; let maxDepth = 0; for (let i = 0; i < pattern.length; i++) { if (pattern[i] === '\\' && i + 1 < pattern.length) { i++; // пропускаем экранированный символ continue; } if (pattern[i] === '(') depth++; else if (pattern[i] === ')') depth--; if (depth < 0) { return false; // некорректная скобочная структура } if (depth > maxDepth) { maxDepth = depth; } } return maxDepth <= 5; } catch { return false; } }