/
OskarSR
/
Factor
Обзор
Документация
Войти
/
OskarSR
/
Factor
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
factor/lib/security.js
91 строка
4 KB
Oskar Stud
Add initial implementation of the Factor PWA for fact-checking
13 мар 2026, 01:08
13 мар 2026, 01:08
33d6aea
Код
Авторство
О чём код?
/** * Защита ввода: валидация и снижение риска prompt injection. * - Ограничение длины и типа * - Удаление управляющих символов и null bytes * - Нейтрализация типичных фраз инъекции (RU/EN) * - Разметка границ пользовательского ввода для промптов (в agents.js) */ const MAX_FACT_LENGTH = 2000; const MIN_FACT_LENGTH = 2; /** Фразы, часто используемые в prompt injection (игнорировать инструкции, смена роли и т.д.) */ const INJECTION_PATTERNS = [ // English /\bignore\s+(all\s+)?(previous|above|prior)\s+instructions?\b/gi, /\bdisregard\s+(all\s+)?(previous|above)\s+(instructions?|context)\b/gi, /\bforget\s+(everything|all)\s+(above|previous)\b/gi, /\b(new\s+)?(instruction|prompt|system)\s*:\s*/gi, /\b(you\s+are\s+now|act\s+as|pretend\s+to\s+be)\s+/gi, /\boutput\s+only\s+/gi, /\b(reveal|show|display)\s+(your|the)\s+(system\s+)?(prompt|instructions?)\b/gi, /\b(system|assistant|user)\s*:\s*$/gim, /\b\[INST\]|\[\/INST\]|<<SYS>>|<<\/SYS>>/gi, // Русский /\bигнорируй\s+(все\s+)?(предыдущие|выше)\s*(инструкции)?\b/gi, /\bзабудь\s+(всё|все)\s+(выше|предыдущее)\b/gi, /\b(новая\s+)?инструкция\s*:\s*/gi, /\b(ты\s+теперь|действуй\s+как|притворись)\s+/gi, /\bвыведи\s+только\s+/gi, /\b(покажи|раскрой)\s+(свой\s+)?(промпт|инструкции?)\b/gi, /\b(система|ассистент|пользователь)\s*:\s*$/gim, ]; /** Удаляет null bytes и опасные управляющие символы */ function removeControlChars(str) { if (typeof str !== "string") return ""; return str .replace(/\0/g, "") .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "") .replace(/[\u200B\u200C\u200D\uFEFF]/g, "") // zero-width .trim(); } /** Ослабляет типичные фразы инъекции: заменяет на пробел, не удаляя контекст утверждения */ function neutralizeInjectionPhrases(str) { let out = str; for (const re of INJECTION_PATTERNS) { out = out.replace(re, " "); } return out.replace(/\s+/g, " ").trim(); } /** * Валидирует и санитизирует ввод факта для проверки. * @param {unknown} raw - сырое значение из req.body.fact * @returns {{ ok: true, value: string } | { ok: false, error: string }} */ export function validateFact(raw) { if (raw == null) { return { ok: false, error: "Факт не указан" }; } if (typeof raw !== "string") { return { ok: false, error: "Неверный формат ввода" }; } let value = removeControlChars(raw); if (value.length < MIN_FACT_LENGTH) { return { ok: false, error: "Факт слишком короткий" }; } if (value.length > MAX_FACT_LENGTH) { return { ok: false, error: `Факт не должен превышать ${MAX_FACT_LENGTH} символов` }; } value = neutralizeInjectionPhrases(value); if (value.length < MIN_FACT_LENGTH) { return { ok: false, error: "После проверки ввод оказался пустым" }; } return { ok: true, value }; } /** * Подготавливает уже провалидированный факт для вставки в промпт: * нормализует пробелы, обрезает по длине (на случай если вызывают без validateFact). */ export function sanitizeForPrompt(validatedFact) { const s = String(validatedFact).slice(0, MAX_FACT_LENGTH); return removeControlChars(s).replace(/\s+/g, " ").trim(); } export { MAX_FACT_LENGTH, MIN_FACT_LENGTH };