import { findHiddenUnicode } from "./unicode-safety.js"; export interface PromptInjectionFinding { kind: "hidden-unicode" | "reversed-tag" | "fake-wrapper" | "role-spoof" | "instruction-smuggling"; index: number; match: string; } const PATTERNS: Array<{ kind: PromptInjectionFinding["kind"]; re: RegExp }> = [ { kind: "reversed-tag", re: />\/?(?:gnikniht|metsys|loot|ekovni|retemarap)(?::lm?tna)?]*>/gi }, { kind: "role-spoof", re: /\b(?:ignore|override|disregard)\s+(?:all\s+)?(?:previous|prior|system|developer)\s+instructions\b/gi }, { kind: "instruction-smuggling", re: /\b(?:system\s+prompt|developer\s+message|hidden\s+instructions?|reveal\s+your\s+prompt|repeat\s+your\s+instructions)\b/gi }, ]; export function findPromptInjection(text: string): PromptInjectionFinding[] { const findings: PromptInjectionFinding[] = findHiddenUnicode(text).map((hit) => ({ kind: "hidden-unicode", index: hit.index, match: hit.codePoint, })); for (const { kind, re } of PATTERNS) { re.lastIndex = 0; for (const match of text.matchAll(re)) { findings.push({ kind, index: match.index, match: match[0].slice(0, 80) }); } } return findings.sort((a, b) => a.index - b.index); }