import { RULE_CATALOG } from "./ruleCatalog"; export type Lang = "de" | "en" | "es"; export const SUPPORTED_LANGS: Lang[] = ["de", "en", "es"]; export function normalizeLang(value: string | null | undefined): Lang { return value === "en" || value === "es" || value === "de" ? value : "de"; } export type RuleText = { category: string; title: string; description: string; remediation: string; }; // German is the canonical source kept inline in RULE_CATALOG. This map only // carries the English and Spanish overrides; de falls back to the catalog. const OVERRIDES: Record = { "SEC-REVERSE-SHELL": { en: { category: "Code execution", title: "Reverse shell / interactive shell", description: "The skill contains patterns typical of reverse shells or of establishing interactive shell connections to a remote host.", remediation: "Remove any code that opens shell connections to external hosts. Such patterns are practically never required in legitimate skills.", }, es: { category: "Ejecución de código", title: "Shell inversa / shell interactiva", description: "El skill contiene patrones típicos de shells inversas o del establecimiento de conexiones de shell interactivas con un host remoto.", remediation: "Elimine cualquier código que abra conexiones de shell con hosts externos. Estos patrones prácticamente nunca son necesarios en skills legítimos.", }, }, "SEC-REMOTE-EXEC": { en: { category: "Code execution", title: "Download-and-execute from the network", description: "Content is downloaded from the internet and piped straight into an interpreter (e.g. curl | bash). This allows uncontrolled execution of foreign code.", remediation: "Never pipe code directly into a shell. Review and version downloaded artifacts before running them.", }, es: { category: "Ejecución de código", title: "Descargar y ejecutar desde la red", description: "Se descarga contenido de internet y se pasa directamente a un intérprete (p. ej. curl | bash). Esto permite la ejecución incontrolada de código ajeno.", remediation: "Nunca canalice código directamente a una shell. Revise y versione los artefactos descargados antes de ejecutarlos.", }, }, "SEC-DESTRUCTIVE": { en: { category: "Destructive operations", title: "Destructive file or disk operation", description: "Potentially destructive commands were detected (recursive deletion, overwriting disks, formatting, fork bomb).", remediation: "Restrict delete operations to clearly scoped paths and avoid operations at the root, home or device level.", }, es: { category: "Operaciones destructivas", title: "Operación destructiva de archivos o disco", description: "Se detectaron comandos potencialmente destructivos (borrado recursivo, sobrescritura de discos, formateo, fork bomb).", remediation: "Limite las operaciones de borrado a rutas claramente delimitadas y evite operaciones a nivel de raíz, home o dispositivo.", }, }, "SEC-PRIV-ESC": { en: { category: "Privilege escalation", title: "Privilege escalation / insecure permissions", description: "The skill tries to gain elevated privileges or sets insecure file permissions (sudo, chmod 777, setuid, chown root).", remediation: "Avoid sudo and overly broad permissions. Grant only the minimum privileges that are strictly necessary.", }, es: { category: "Escalada de privilegios", title: "Escalada de privilegios / permisos inseguros", description: "El skill intenta obtener privilegios elevados o establece permisos de archivo inseguros (sudo, chmod 777, setuid, chown root).", remediation: "Evite sudo y permisos demasiado amplios. Conceda únicamente los privilegios mínimos estrictamente necesarios.", }, }, "SEC-PERSISTENCE": { en: { category: "Persistence", title: "Persistence mechanism", description: "The skill may set up persistent mechanisms (cron jobs, systemd services, shell profile hooks, SSH keys).", remediation: "Persistence should only happen with explicit consent. Verify whether creating autostart entries is really necessary.", }, es: { category: "Persistencia", title: "Mecanismo de persistencia", description: "El skill podría configurar mecanismos persistentes (cron jobs, servicios systemd, hooks del perfil de shell, claves SSH).", remediation: "La persistencia solo debe producirse con consentimiento explícito. Compruebe si crear entradas de inicio automático es realmente necesario.", }, }, "SEC-OBFUSCATION": { en: { category: "Obfuscation", title: "Obfuscated or dynamically executed code", description: "Indications of obfuscated code or dynamic execution were found (base64 decoding with execution, eval/exec, hex escapes).", remediation: "Avoid dynamic code execution and obfuscation. Code should be readable in plain text.", }, es: { category: "Ofuscación", title: "Código ofuscado o ejecutado dinámicamente", description: "Se encontraron indicios de código ofuscado o ejecución dinámica (decodificación base64 con ejecución, eval/exec, escapes hexadecimales).", remediation: "Evite la ejecución dinámica de código y la ofuscación. El código debe ser legible en texto plano.", }, }, "SEC-SUPPLY-CHAIN": { en: { category: "Supply chain", title: "Insecure package or source installation", description: "Packages are installed from untrusted sources (direct URLs, git+ sources, external apt repositories or keys).", remediation: "Install packages only from trusted, versioned sources and avoid installing directly from URLs.", }, es: { category: "Cadena de suministro", title: "Instalación insegura de paquetes o fuentes", description: "Se instalan paquetes desde fuentes no confiables (URLs directas, fuentes git+, repositorios o claves apt externos).", remediation: "Instale paquetes solo desde fuentes confiables y versionadas y evite instalar directamente desde URLs.", }, }, "SEC-NETWORK": { en: { category: "Network", title: "Outbound network access", description: "The skill establishes outbound network connections. This is not necessarily malicious but should be assessed.", remediation: "Make sure the contacted endpoints are expected and trustworthy.", }, es: { category: "Red", title: "Acceso de red saliente", description: "El skill establece conexiones de red salientes. Esto no es necesariamente malicioso, pero debe evaluarse.", remediation: "Asegúrese de que los endpoints contactados sean esperados y confiables.", }, }, "PRIV-SECRET-ACCESS": { en: { category: "Access to secrets", title: "Access to credentials or secrets", description: "The skill accesses typical secret storage locations (.env, SSH keys, cloud credentials, .netrc, environment variables).", remediation: "Avoid accessing secret files. If required, document the purpose and scope transparently.", }, es: { category: "Acceso a secretos", title: "Acceso a credenciales o secretos", description: "El skill accede a ubicaciones típicas de almacenamiento de secretos (.env, claves SSH, credenciales de la nube, .netrc, variables de entorno).", remediation: "Evite acceder a archivos de secretos. Si es necesario, documente el propósito y el alcance de forma transparente.", }, }, "PRIV-EXFILTRATION": { en: { category: "Data exfiltration", title: "Possible data exfiltration", description: "Data is sent to external endpoints (HTTP POST with payloads, file uploads). Combined with secret access this is highly critical.", remediation: "Do not send local data to external servers without explicit, documented consent.", }, es: { category: "Fuga de datos", title: "Posible exfiltración de datos", description: "Se envían datos a endpoints externos (HTTP POST con datos, subida de archivos). Combinado con acceso a secretos esto es altamente crítico.", remediation: "No envíe datos locales a servidores externos sin consentimiento explícito y documentado.", }, }, "PRIV-PROMPT-INJECTION": { en: { category: "Prompt injection", title: "Prompt injection / instruction manipulation", description: "The instructions contain wording that manipulates agent behaviour (ignore previous instructions, deceive the user, bypass safety guardrails).", remediation: "Remove manipulative instructions. A skill must not instruct the agent to bypass safety rules or deceive the user.", }, es: { category: "Inyección de prompts", title: "Inyección de prompts / manipulación de instrucciones", description: "Las instrucciones contienen formulaciones que manipulan el comportamiento del agente (ignorar instrucciones previas, engañar al usuario, eludir las barreras de seguridad).", remediation: "Elimine las instrucciones manipuladoras. Un skill no debe indicar al agente que eluda las reglas de seguridad ni que engañe al usuario.", }, }, "PRIV-HIDDEN-INSTRUCTIONS": { en: { category: "Hidden content", title: "Hidden or invisible instructions", description: "Invisible Unicode characters or hidden comments were found in the text that could conceal instructions from humans.", remediation: "Remove invisible control characters and hidden comments. All instructions must be visible to humans.", }, es: { category: "Contenido oculto", title: "Instrucciones ocultas o invisibles", description: "Se encontraron caracteres Unicode invisibles o comentarios ocultos en el texto que podrían ocultar instrucciones a las personas.", remediation: "Elimine los caracteres de control invisibles y los comentarios ocultos. Todas las instrucciones deben ser visibles para las personas.", }, }, "PRIV-PII": { en: { category: "Data protection / GDPR", title: "Collection of personal data", description: "The skill refers to collecting or processing personal or sensitive data (passwords, credit cards, ID documents, date of birth).", remediation: "Only collect personal data with a legal basis and document the purpose, scope and storage in accordance with the GDPR.", }, es: { category: "Protección de datos / RGPD", title: "Recopilación de datos personales", description: "El skill hace referencia a la recopilación o el tratamiento de datos personales o sensibles (contraseñas, tarjetas de crédito, documentos de identidad, fecha de nacimiento).", remediation: "Recopile datos personales únicamente con una base legal y documente el propósito, el alcance y el almacenamiento conforme al RGPD.", }, }, "PRIV-AGENT-TAMPERING": { en: { category: "System compromise", title: "Tampering with the agent or other skills", description: "The skill may try to modify or delete the agent, its memory or other skills/configurations.", remediation: "A skill must not modify the agent, other skills, memory or configuration files.", }, es: { category: "Compromiso del sistema", title: "Manipulación del agente o de otros skills", description: "El skill podría intentar modificar o eliminar el agente, su memoria u otros skills/configuraciones.", remediation: "Un skill no debe modificar el agente, otros skills, la memoria ni los archivos de configuración.", }, }, "PRIV-OVERREACH": { en: { category: "Permissions", title: "Excessive permission request", description: "The skill requests very broad or unrestricted permissions.", remediation: "Request only the minimum necessary permissions (principle of least privilege).", }, es: { category: "Permisos", title: "Solicitud excesiva de permisos", description: "El skill solicita permisos muy amplios o sin restricciones.", remediation: "Solicite únicamente los permisos mínimos necesarios (principio de mínimo privilegio).", }, }, "AI-PROMPT-INJECTION": { en: { category: "AI analysis", title: "AI: Covert prompt injection", description: "Semantic AI analysis for covert or subtle attempts to manipulate agent behaviour that static rules do not catch.", remediation: "Manually review the spots flagged by the AI and remove manipulative content.", }, es: { category: "Análisis con IA", title: "IA: Inyección de prompts encubierta", description: "Análisis semántico con IA para detectar intentos encubiertos o sutiles de manipular el comportamiento del agente que las reglas estáticas no captan.", remediation: "Revise manualmente los puntos marcados por la IA y elimine el contenido manipulador.", }, }, "AI-MALICIOUS-INTENT": { en: { category: "AI analysis", title: "AI: Malicious intent in the code", description: "Semantic AI analysis for malicious or hidden functionality in the code that goes beyond pure pattern matching.", remediation: "Manually review the flagged code sections for malicious intent.", }, es: { category: "Análisis con IA", title: "IA: Intención maliciosa en el código", description: "Análisis semántico con IA para detectar funcionalidad maliciosa u oculta en el código que va más allá de la mera coincidencia de patrones.", remediation: "Revise manualmente las secciones de código marcadas en busca de intención maliciosa.", }, }, "AI-DATA-PRIVACY": { en: { category: "AI analysis", title: "AI: Data protection risk", description: "Semantic AI analysis for data protection risks and possible leakage of personal data.", remediation: "Assess the flagged data protection risks and ensure GDPR compliance.", }, es: { category: "Análisis con IA", title: "IA: Riesgo de protección de datos", description: "Análisis semántico con IA para detectar riesgos de protección de datos y posible fuga de datos personales.", remediation: "Evalúe los riesgos de protección de datos marcados y garantice el cumplimiento del RGPD.", }, }, }; // Built lazily to avoid a circular module-init crash: ruleCatalog imports this // file, so RULE_CATALOG is in the temporal dead zone while this module first // evaluates. Touching it only inside a function defers access until runtime. let deById: Map | null = null; function getDeById(): Map { if (!deById) { deById = new Map( RULE_CATALOG.map((r) => [ r.ruleId, { category: r.category, title: r.title, description: r.description, remediation: r.remediation, } satisfies RuleText, ]), ); } return deById; } /** Localized text for a rule. Falls back to the German catalog if unknown. */ export function localizeRule(ruleId: string, lang: Lang): RuleText { const de = getDeById().get(ruleId) ?? { category: "", title: ruleId, description: "", remediation: "", }; if (lang === "de") return de; const override = OVERRIDES[ruleId]; return override ? override[lang] : de; } // Generated snippet text used by the hidden-instructions heuristic, localized so // findings never leak German into EN/ES reports. export const INVISIBLE_CHAR_SNIPPET_DE = "Unsichtbares Steuerzeichen in dieser Zeile erkannt."; const INVISIBLE_CHAR_SNIPPET: Record = { de: INVISIBLE_CHAR_SNIPPET_DE, en: "Invisible control character detected on this line.", es: "Carácter de control invisible detectado en esta línea.", }; export function localizeSnippet(snippet: string, lang: Lang): string { if (snippet === INVISIBLE_CHAR_SNIPPET_DE) { return INVISIBLE_CHAR_SNIPPET[lang]; } return snippet; }