Vulnerabilidades de la cadena de suministro
Descripción
Las aplicaciones de LLM dependen de modelos, conjuntos de datos, complementos y frameworks de terceros que pueden estar comprometidos. Los ataques a la cadena de suministro introducen vulnerabilidades a través de las dependencias.
Riesgo
El ecosistema de LLM incluye numerosas dependencias externas, entre ellas modelos preentrenados, conjuntos de datos, herramientas de ajuste fino, complementos y marcos de inferencia. Las dependencias comprometidas pueden introducir puertas traseras, exfiltración de datos o comportamiento malicioso que persiste a lo largo del ciclo de vida de la aplicación. Los ataques a la cadena de suministro son difíciles de detectar y pueden afectar a múltiples sistemas posteriores.
Escenarios de ataque
Un atacante sube un modelo envenenado a un repositorio público con un nombre similar al de un modelo legítimo popular. Los desarrolladores, sin saberlo, descargan e despliegan la versión maliciosa.
Un complemento de terceros para una aplicación de LLM contiene código oculto que exfiltra los prompts y las respuestas de los usuarios a un servidor externo controlado por el atacante.
Mitigaciones
Verificación de dependencias
Verificar las sumas de verificación y las firmas de todos los modelos y dependencias descargados. Mantener una lista aprobada de fuentes y repositorios confiables.
Lista de materiales de software
Mantener un SBOM integral que rastree todos los componentes, versiones y orígenes del LLM. Supervisar las vulnerabilidades conocidas en las dependencias.
Sandboxing
Ejecutar los complementos y modelos de terceros en entornos aislados con permisos limitados. Implementar controles de acceso estrictos para los recursos sensibles.
Auditorías periódicas
Realizar revisiones de seguridad de todas las dependencias. Supervisar las actualizaciones, parches y avisos de seguridad de los proveedores.
Ejemplos de código
# Correcto: Verificación de modelos y sandboxing
import hashlib
import json
from pathlib import Path
class CargadorModeloSeguro:
def __init__(self, ruta_registro_confiable: str):
with open(ruta_registro_confiable) as f:
self.registro = json.load(f)
def verificar_modelo(self, ruta_modelo: str, id_modelo: str) -> bool:
# Verificar contra el registro confiable
if id_modelo not in self.registro:
raise ValueError(f"El modelo {id_modelo} no está en el registro confiable")
# Verificar la suma de verificación
hash_esperado = self.registro[id_modelo]['sha256']
hash_real = self._calcular_hash(ruta_modelo)
if hash_real != hash_esperado:
raise ValueError("Suma de verificación del modelo no coincide - posible manipulación")
return True
def _calcular_hash(self, ruta: str) -> str:
sha256 = hashlib.sha256()
with open(ruta, 'rb') as f:
for fragmento in iter(lambda: f.read(8192), b''):
sha256.update(fragmento)
return sha256.hexdigest()
Requisitos de evidencia
- Lista de materiales de software (SBOM) para todas las dependencias del LLM
- Registros de verificación de sumas de verificación de modelos y conjuntos de datos
- Listas de proveedores y repositorios aprobados
- Informes de escaneo de vulnerabilidades de dependencias
- Resultados de auditorías de seguridad de terceros para complementos