LLM02
OWASP LLM Top 10 DATOS MODELO

Manejo inseguro de salidas

Descripción

Las salidas del LLM se pasan a sistemas posteriores o se renderizan sin validación. Esto genera vulnerabilidades de inyección cuando las salidas contienen código o comandos maliciosos.

Riesgo

Tratar las salidas del LLM como datos confiables permite ataques de inyección en sistemas posteriores. Las salidas pueden contener inyección SQL, XSS, inyección de comandos u otras cargas maliciosas que se ejecutan al ser procesadas por sistemas de backend o renderizadas en interfaces de usuario. Esto puede provocar filtraciones de datos, compromiso del sistema y escalamiento de privilegios.

Escenarios de ataque

Una función de búsqueda basada en LLM genera consultas SQL a partir de lenguaje natural. Un atacante diseña una entrada que hace que el LLM genere SQL malicioso que elimina tablas al ejecutarse.

Un sistema de generación de contenido renderiza las salidas del LLM directamente en HTML sin sanitización, lo que permite que el modelo inyecte JavaScript que roba tokens de sesión de otros usuarios.

Mitigaciones

Validación de salidas

Validar y sanitizar todas las salidas del LLM antes de usarlas. Tratar las salidas como entrada de usuario no confiable y aplicar los mismos controles de seguridad.

Interfaces parametrizadas

Utilizar consultas parametrizadas, sentencias preparadas y API seguras al pasar salidas del LLM a sistemas de backend. Nunca construir comandos o consultas mediante concatenación de cadenas.

Política de seguridad de contenido

Aplicar encabezados CSP y codificación de salida al renderizar contenido del LLM en aplicaciones web. Utilizar escapado sensible al contexto según el destino de la salida.

Ejecución con mínimo privilegio

Ejecutar los sistemas posteriores con los permisos mínimos requeridos. Limitar el impacto de los ataques de inyección exitosos mediante defensa en profundidad.

Ejemplos de código

# Incorrecto: Ejecución directa de la salida del LLM
consulta = llm.complete(f"Generar SQL para: {solicitud_usuario}")
bd.execute(consulta)  # Riesgo de inyección SQL

# Correcto: Validar y usar consultas parametrizadas
import re
from typing import Optional

def validar_salida_sql(salida_llm: str) -> Optional[dict]:
    # Analizar la salida estructurada, rechazar SQL libre
    if not salida_llm.startswith('{'):
        return None
    analizado = json.loads(salida_llm)
    operaciones_permitidas = ['SELECT', 'INSERT', 'UPDATE']
    if analizado.get('operation') not in operaciones_permitidas:
        return None
    return analizado

salida_llm = llm.complete(f"Generar plan de consulta: {solicitud_usuario}")
plan_consulta = validar_salida_sql(salida_llm)
if plan_consulta:
    # Usar ejecución parametrizada segura
    bd.execute(
        "SELECT * FROM products WHERE category = ?",
        (plan_consulta['category'],)
    )

Requisitos de evidencia

  • Revisiones de código que muestren la validación de salidas antes del procesamiento posterior
  • Uso de consultas parametrizadas y sentencias preparadas
  • Codificación de salida e implementación de CSP para el renderizado web
  • Informes de pruebas de seguridad que validen la resistencia a la inyección
  • Documentación de los requisitos de seguridad para el manejo de salidas