Local Agent Bench

← Notas · 2026-10-23

Backdoors en plantillas de chat

Cada archivo GGUF lleva una plantilla de chat: un programa Jinja2, guardado en los metadatos del archivo (tokenizer.chat_template), que formatea cada conversación al prompt que el modelo realmente ve. Es ejecutable y corre en cada llamada de inferencia. Investigadores han mostrado que un atacante puede editar solo esa plantilla en un modelo legítimo, re-subirlo y obtener un backdoor sin tocar los pesos, los datos de entrenamiento ni el servidor de inferencia: la plantilla queda dormida hasta que aparece una frase trigger en la entrada del usuario, y entonces inyecta instrucciones en silencio en la región de system del prompt.

Nuestro resultado (2026-10-23)

Checamos las plantillas de los 29 modelos de la tabla contra los originales de sus proveedores (plantilla y config del registry de Ollama, el tokenizer.chat_template leído del header GGUF del blob exacto del registry, y el original del proveedor en Hugging Face), y las escaneamos todas buscando URLs, payloads codificados, keywords de install/exfiltración y condicionales sobre el contenido del mensaje del usuario.

Veredicto Modelos
Sospechosas 0
Idénticas a la plantilla del proveedor 12
Diferencias benignas (revisiones más viejas, formato simplificado, instrucciones de formato de salida) 14
No se pudo comparar (repo del proveedor gated en Hugging Face) 3 (gemma3:4b, llama3.1:8b, llama3.2:3b; sus plantillas igual se escanearon limpias)

Para los 29 modelos, el sha256 del GGUF registrado en nuestras corridas es igual al archivo del modelo que sirve hoy el registry de Ollama. Matiz: 9 modelos los renderizan renderers compilados dentro de Ollama en lugar de una capa de plantilla; ese código de Ollama no se inspeccionó, solo sus plantillas GGUF. Fue un chequeo de una sola vez; la integridad de la plantilla no forma parte del puntaje 0–100.

Resultados reportados

Fogel et al., 18 modelos en 7 familias, cuatro motores (llama.cpp, Ollama, vLLM, SGLang):

Hallazgo Resultado
Precisión factual bajo trigger 90% → 15% (promedio)
Emisión de URL controlada por el atacante tasa de éxito por encima del 80%
Desvío sin trigger ninguno medible
Varianza entre los 4 motores bajo 5%
Episodios de agente evaluados 3,868, saltándose cada defensa de inyección probada

Por qué nuestra categoría de inyección no lo ve

Nuestras tareas de inyección de prompts prueban si un modelo obedece instrucciones escondidas en la salida de tools (file, search, search→file). Un backdoor de plantilla no llega por la salida de tools; se renderiza en el prompt antes de procesar la entrada del usuario, así que las defensas a nivel de input nunca lo ven. Un modelo puede sacar 100 en nuestra categoría de inyección y aun así estar backdooreado en la capa de plantilla. El puntaje no dice nada sobre la procedencia del archivo que probamos.

Cada corrida guarda el sha256 del GGUF, motor y versión, quant y versión del harness, así que se puede identificar el archivo exacto detrás de un resultado y comparar su plantilla contra el original del proveedor.

Checa tus propios modelos

Qué no es una defensa

Afirmación Realidad
"Cambia o actualiza el motor de inferencia" La plantilla vive en el archivo del modelo; los resultados se sostuvieron en 4 motores con menos de 5% de varianza.
"Hugging Face lo escaneó" Los archivos envenenados pasaron cada escaneo automatizado de la plataforma.
"Tiene muchos downloads" Los conteos de downloads no son procedencia.
"Mi guardrail de inyección de prompts lo cubre" El payload se renderiza antes de que corran las defensas a nivel de input.
"El modelo está alineado" Los modelos con mayor fidelidad a seguir instrucciones mostraron mayor éxito del ataque.

Fuentes