Los asistentes de IA escriben ya una gran parte del código nuevo en muchos equipos. Ese código pasa por los mismos compiladores y los mismos servidores de producción que el código humano, pero falla de otra manera. Es fluido, seguro de sí mismo y a menudo correcto, lo que hace más difícil detectar las partes incorrectas. Este artículo resume lo que ha encontrado la investigación en seguridad sobre el código generado por IA, explica el nuevo riesgo de cadena de suministro de los paquetes alucinados y expone los controles que uso para que programar más rápido no signifique más incidentes.

Qué dice la investigación

Varios estudios han analizado la seguridad del código producido con ayuda de IA:

  • Las sugerencias vulnerables son habituales en escenarios de riesgo. Unos investigadores plantearon a GitHub Copilot 89 escenarios diseñados en torno a debilidades CWE; alrededor del 40% de los 1.689 programas generados contenían vulnerabilidades (Pearce et al., "Asleep at the Keyboard?"). Los modelos han mejorado desde entonces, pero esos escenarios —consultas SQL, manejo de rutas, criptografía— siguen siendo donde se concentran los errores.
  • Los desarrolladores con asistentes escriben código menos seguro y se sienten más seguros de él. En un estudio con usuarios en Stanford, los participantes con acceso a un asistente de IA escribieron código significativamente menos seguro en varias tareas y tenían más probabilidades de creer que su código era seguro (Perry et al., 2023).
  • Las alucinaciones de paquetes son sistemáticas. En 576.000 muestras de código de 16 modelos, el 19,7% de los paquetes recomendados no existía; los investigadores contaron más de 205.000 nombres únicos de paquetes alucinados, y muchos se repetían de forma consistente entre ejecuciones (Spracklen et al., 2024).

La segunda conclusión es la más importante para diseñar el proceso: el riesgo no está solo en el código, está en el menor escrutinio. Los controles deben compensar el exceso de confianza.

Las clases de vulnerabilidades que vigilar

El código generado por IA tiende a reproducir patrones habituales en el código público, incluidos los inseguros. Los sospechosos habituales se corresponden directamente con el OWASP Top 10:2025:

Debilidad Forma típica generada por IA Control
Inyección (SQL, comandos, plantillas) Consultas construidas con cadenas, shell=True, plantillas sin escapar APIs parametrizadas, reglas de Semgrep, lista de revisión
Control de acceso roto Endpoint nuevo copiado de uno público sin comprobación de autorización Middleware con autenticación por defecto, tests de rutas
Fallos criptográficos MD5/SHA1 para contraseñas, IVs fijos en el código, tokens con Math.random() Envoltorios criptográficos aprobados, linters
Configuración de seguridad incorrecta CORS: *, modo debug activado, flags de cookies permisivos Plantillas de configuración, escaneo de IaC
SSRF Descargar en el servidor URLs proporcionadas por el usuario Listas de permitidos, controles de salida de red
Secretos en el código Claves de API de ejemplo olvidadas en el código Escaneo de secretos, push protection
Deserialización pickle.loads, serialización nativa de Java sobre la entrada Lista de APIs prohibidas

Ninguna de ellas es nueva. Lo nuevo es el volumen: cuando un agente escribe 500 líneas en un minuto, un solo patrón copiado puede aparecer en una docena de sitios.

Slopsquatting: el ataque de las dependencias alucinadas

Cuando un modelo sugiere pip install fastapi-auth-helpers y el paquete no existe, un atacante puede registrarlo con código malicioso. Como los modelos repiten las mismas alucinaciones, los atacantes pueden recopilar los nombres probables preguntando ellos mismos a los modelos. Este ataque se ha bautizado como slopsquatting, una variante del typosquatting dirigida a las máquinas en lugar de a las personas.

Las herramientas agénticas lo empeoran: un agente que ve un error de importación puede ejecutar él mismo el comando de instalación. Defensas:

  1. Nunca apruebes automáticamente la instalación de dependencias en los permisos del agente.
  2. Verifica cada dependencia nueva: ¿existe?, ¿quién la mantiene?, ¿qué antigüedad tiene?, ¿cuántas descargas?, ¿coincide el enlace al repositorio? Herramientas como OpenSSF Scorecard y deps.dev ayudan.
  3. Usa un proxy de registro privado (Artifactory, Nexus, Verdaccio, un espejo de pip/npm) con lista de permitidos o una política de antigüedad mínima para los paquetes nuevos.
  4. Los archivos de lock y los hashes de integridad deben estar en el repositorio y verificarse en CI.
  5. Genera un SBOM y escanéalo en cada build.

Controles por capas para el desarrollo asistido por IA

Piensa en los controles en cuatro capas, desde el teclado del desarrollador hasta producción.

Capa 1: el propio asistente

  • Instrucciones de seguridad en el archivo del proyecto. Añade una sección breve a CLAUDE.md o AGENTS.md: "Usa db.query() con parámetros; nunca construyas SQL con cadenas. Todas las rutas nuevas pasan por withAuth(). No añadas dependencias sin preguntar". Los asistentes siguen mucho mejor las reglas concretas que los prompts genéricos de "escribe código seguro".
  • Permisos restringidos. Nada de red, instalaciones ni acceso a archivos de credenciales sin confirmación. Consulta buenas prácticas de agentic coding.
  • Hooks que bloqueen las ediciones en rutas sensibles (autenticación, criptografía, pagos) o exijan a una persona para ellas.

Capa 2: antes del commit

  • Escaneo de secretos en pre-commit con Gitleaks o similar.
  • SAST rápido con reglas de Semgrep ajustadas a tu stack. Las reglas propias para tus APIs internas ("nunca llames a rawQuery") detectan exactamente los patrones que copia un asistente.
  • Revisión de cada línea por parte del desarrollador. La responsabilidad es de la persona que hace el commit.

Capa 3: pull request y CI

  • SAST completo con CodeQL o equivalente, más escaneo de dependencias.
  • Revisión de seguridad con IA como pasada adicional, con un prompt que incluya tu modelo de amenazas y los patrones prohibidos; consulta revisión de código con IA. Es buena explicando por qué algo es peligroso, lo que ayuda a los desarrolladores a aprender.
  • Puerta para dependencias nuevas: un job de CI que falla cuando un archivo de lock añade un paquete, hasta que una persona lo aprueba.
  • Tests de propiedades de seguridad: tests de autorización para cada ruta y de validación de entrada para los parsers.

Capa 4: ejecución

  • Cuentas de servicio con mínimo privilegio y controles de salida de red limitan el alcance de cualquier vulnerabilidad que se escape.
  • WAF y límites de frecuencia delante de los endpoints públicos.
  • Observabilidad y alertas sobre fallos de autenticación, consultas inusuales y picos de errores.

Un ejemplo de regla de Semgrep

Las reglas propias son donde codificas los peligros específicos de tu código. Esta regla señala el SQL construido con cadenas usando un cliente propio del proyecto:

rules:
  - id: no-string-built-sql
    languages: [typescript]
    severity: ERROR
    message: >
      Build SQL with db.query(sql, params). String concatenation or template
      literals with variables enable SQL injection.
    patterns:
      - pattern-either:
          - pattern: db.query(`...${$X}...`)
          - pattern: db.query("..." + $X + "...")

Reglas así cuestan minutos de escribir y segundos de ejecutar, y convierten una lección aprendida una vez en una comprobación que se ejecuta para siempre.

Prompts orientados a la seguridad, sin depender de ellos

Los prompts centrados en la seguridad ayudan en el margen. Pedir a un asistente que "enumere las suposiciones de seguridad de esta función y las entradas que controla un atacante" antes de implementar produce mejor código que pedir directamente la implementación. Pedirle que escriba tests negativos —entrada no válida, permisos que faltan, cargas sobredimensionadas— detecta pronto clases enteras de bugs.

Pero un prompt no es un control. Los modelos pueden ser dirigidos por contenido malicioso en el contexto —un README envenenado, la descripción de un issue, el docstring de una dependencia—, que es el problema de prompt injection descrito en seguridad de agentes de IA. Lo que de verdad impone la política son las comprobaciones deterministas de las capas 2 a 4.

Licencias y procedencia

La seguridad también incluye la exposición legal. Algunos proveedores ofrecen filtros que bloquean las sugerencias que coinciden con código público o muestran referencias a la fuente. Actívalos en productos propietarios, mantén el escaneo de licencias en CI y anota en la descripción del PR cuándo grandes bloques de código vienen de un asistente. En entornos regulados, este rastro de procedencia también ayuda con los requisitos de auditoría.

Una lista de comprobación para equipos

  • El archivo de instrucciones del proyecto contiene reglas de seguridad concretas para tu stack
  • Los agentes no pueden instalar paquetes, acceder a la red ni leer secretos sin aprobación
  • El escaneo de secretos en pre-commit está activado para todos los desarrolladores
  • El SAST con reglas propias se ejecuta en cada PR
  • Las dependencias nuevas requieren la aprobación explícita de una persona
  • Los archivos de lock y los SBOM se generan y escanean en cada build
  • Cada ruta tiene un test de autorización
  • La revisión con IA se ejecuta con tu modelo de amenazas, y las personas siguen aprobando
  • La formación en seguridad cubre los riesgos específicos de la IA: exceso de confianza, paquetes alucinados, prompt injection

Preguntas frecuentes

¿El código generado por IA es menos seguro que el humano? La investigación sugiere que los desarrolladores que usan asistentes tienen más probabilidades de aceptar patrones inseguros y menos de notarlos. El código no es intrínsecamente peor; la revisión que lo rodea a menudo sí.

¿Deberíamos prohibir los asistentes de IA en módulos críticos para la seguridad? Muchos equipos impiden que los agentes editen el código de autenticación, criptografía y pagos sin revisión de un perfil senior. Es razonable. Una prohibición general suele llevar el uso a la clandestinidad.

¿Los modelos nuevos siguen alucinando paquetes? Con menos frecuencia, pero no nunca, y a los atacantes les basta con que ocurra de vez en cuando. Verificar es barato; mantenlo.

¿Podemos dejar que la IA arregle las vulnerabilidades que encuentran los escáneres? Sí, y funciona bien con patrones conocidos. Revisa el arreglo y añade un test que fallaría con la versión vulnerable.

Fuentes

  1. Pearce et al. (2021). Asleep at the Keyboard? Assessing the Security of GitHub Copilot's Code Contributions.
  2. Perry et al. (2023). Do Users Write More Insecure Code with AI Assistants?
  3. Spracklen et al. (2024). We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs.
  4. OWASP. OWASP Top 10:2025 y Top 10 for LLM Applications.
  5. OpenSSF. Scorecard; Google. deps.dev.
  6. Semgrep. Writing rules.