Seguridad y protección
Rosetta está diseñado para ser seguro en entornos adversos, donde los datos de configuración regional pueden provenir de fuentes no confiables, donde los nombres de archivo manipulados podrían escapar de los límites del directorio y donde la salida del LLM puede contener cualquier cosa.
Modelo de amenazas
| Amenaza | Vector de ataque | Mitigación |
|---|---|---|
| Prototype pollution | Claves JSON manipuladas (__proto__, constructor) | Rechazadas en el momento del análisis |
| Path traversal | Códigos de configuración regional como ../../etc/passwd | Escrituras de archivos validadas en los directorios configurados |
| Corrupción de bloques de código | El LLM traduce dentro de los bloques de código | Protección mediante centinelas Unicode |
| Claves alucinadas | El LLM devuelve claves que no se enviaron | Validación de respuesta: solo se escriben las claves aceptadas |
| Gasto descontrolado de tokens | Bucles de reintento infinitos | Límite de presupuesto a través de maxRetries |
Protección contra Prototype Pollution
Todas las claves de configuración regional se validan contra una lista de bloqueo antes de su procesamiento:
__proto__constructorprototype
Cualquier clave que coincida con estos patrones se rechaza con un error. Esto evita que los atacantes utilicen archivos de configuración regional manipulados para modificar los prototipos de objetos de JavaScript.
Contención de rutas
Al escribir archivos de configuración regional, rosetta valida que la ruta de salida se mantenga dentro de los directorios configurados (localesDir, contentDir). Los códigos de configuración regional se desinfectan; un código como ../../secrets no puede escribir fuera del directorio esperado.
Protección de bloques
Durante la traducción de contenido Markdown, los elementos estructurados se reemplazan con marcadores de posición centinelas Unicode antes de enviar el texto al LLM:
- Bloques de código (delimitados y en línea) → centinela
- Shortcodes de Hugo (
{{< >}},{{% %}}) → centinela - HTML sin procesar → centinela
- Variables de interpolación (
{{ .Count }}) → centinela
Después de la traducción, los centinelas se reemplazan con el contenido original. El LLM nunca ve los bloques de código, los shortcodes ni el HTML, por lo que no puede corromperlos.
Validación de respuestas
Cuando el LLM devuelve una respuesta JSON, rosetta valida que:
- Solo las claves que se enviaron en el lote aparezcan en la respuesta
- No se inyecten claves adicionales
- La respuesta se analice como un JSON válido
Las claves alucinadas se descartan silenciosamente. Esto evita que la salida del LLM inyecte traducciones inesperadas en sus archivos de configuración regional.
Quality Gate
Cada traducción se valida mediante cinco comprobaciones deterministas antes de escribirse en el disco. Consulte Quality Gate para obtener más detalles.
Retroceso exponencial
Las llamadas a la API utilizan un retroceso exponencial con fluctuación (jitter) en las respuestas 429 (límite de velocidad) y 5xx (error del servidor). Tres reintentos con un retraso creciente evitan saturar la API durante las interrupciones.
Tiempo de espera de la solicitud
Cada solicitud a la API tiene un tiempo de espera de 30 segundos a través de AbortController. Esto evita que el proceso de sincronización se cuelgue indefinidamente en una conexión inactiva.
Fallos de traducción Fail-Loud
Cuando la API no está disponible o una traducción falla, rosetta lanza un error visible con orientación práctica en lugar de escribir basura silenciosamente. Nunca se escriben marcadores de posición con el prefijo [EN] durante la sincronización.
[ERR] Content sync for fr: no API key available.
Set OPENROUTER_API_KEY in .env.local to translate content.
El fallo de un archivo no detiene toda la sincronización: el error se registra y el pipeline continúa con el siguiente archivo, para que usted obtenga el máximo progreso por ejecución.
Verificación posterior a la sincronización
Una vez completadas todas las traducciones, rosetta vuelve a leer los archivos de configuración regional escritos en el disco y ejecuta un paso de verificación. Esto detecta la brecha entre el éxito reportado por la sincronización y las traducciones que en realidad son incorrectas:
- Paridad de claves: todas las claves de origen están presentes en cada destino
- Marcadores
[EN]: marcadores de respaldo heredados de ejecuciones anteriores - Traducciones vacías: valores en blanco que se filtraron
- Cumplimiento del sistema de escritura: configuraciones regionales no latinas con traducciones que solo contienen ASCII
- Preservación de marcadores de posición: los marcadores de posición ICU coinciden con el origen
Omita con --no-verify o ejecútelo de forma independiente con npx i18n-rosetta verify.
Pruebas
Las propiedades de seguridad se verifican mediante el conjunto de pruebas adversarias:
npm run test:redteam # prototype pollution, path traversal, encoding attacks
Consulte también
- Arquitectura: cómo se conecta el ecosistema de tres piezas
- Referencia de la CLI: integrity: comando de comprobación de integridad
- Referencia de la CLI: provenance: comando de auditoría de procedencia
- Especificación de plugins: campos de procedencia en los manifiestos de plugins
- Quality Gate: comprobaciones de seguridad a nivel de traducción