Secure Code Review para código IA: qué observa realmente un revisor humano

Qué observa realmente un revisor humano en el código generado por IA

Una pull request generada con IA puede ser ordenada, legible y estar llena de pruebas en verde. Puede seguir el estilo del proyecto, actualizar la documentación, corregir errores visibles y cerrar una funcionalidad en pocas horas. El problema es que la seguridad no se evalúa mirando si el código compila o si la demo funciona: es necesario entender qué ha cambiado realmente en el comportamiento de la aplicación.

Una Secure Code Review (revisión de código seguro) sobre código generado o modificado por IA no busca “errores de la IA” en abstracto. Lee el diff dentro del producto: qué datos se ven afectados, qué rutas están expuestas, qué roles pueden ejecutar acciones, qué consultas cambian, qué secretos entran en el perímetro, qué dependencias se han añadido, qué pruebas se han modificado y qué configuración llegará a producción.

Para desarrolladores, CTOs y empresas de software, el punto crítico es este: el código generado por IA puede ser plausible incluso cuando introduce una regresión de seguridad. Una revisión humana sirve para conectar el código, la lógica de negocio, los límites de confianza (trust boundaries), el despliegue y el riesgo real antes de que el merge se convierta en una vulnerabilidad en producción.

Por qué una revisión funcional no es suficiente

La revisión funcional pregunta si la funcionalidad hace lo que se solicitaba. La Secure Code Review pregunta además qué puede ser objeto de abuso, qué suposiciones han cambiado y qué controles se han debilitado. Esta diferencia es crucial cuando el código ha sido generado por IA, porque el asistente tiende a optimizar para completar la tarea, no para preservar límites de seguridad que no están explícitos en el prompt.

Un revisor humano lee el código con preguntas distintas a las de la demo: qué sucede si el usuario cambia un ID, si el token ha caducado, si el rol es bajo, si el inquilino (tenant) es diferente, si la carga de archivos contiene un archivo inesperado, si una dependencia ejecuta scripts, si una variable privada termina en el frontend, si la pipeline se salta un control.

Los escáneres ayudan, pero no sustituyen esta lectura. SAST, el escaneo de dependencias, el escaneo de secretos y los linters interceptan patrones útiles, pero no siempre comprenden la lógica de negocio, el aislamiento de inquilinos, los estados del flujo de trabajo, el abuso de funciones legítimas, la semántica de los roles o el impacto de una refactorización de múltiples archivos.

El primer control: qué ha cambiado realmente la PR

Las PR generadas por IA pueden ser extensas: un prompt pide “añadir esta funcionalidad” y el agente modifica rutas, componentes, middleware, pruebas, esquemas de datos, dependencias, configuraciones y documentación. El diff es coherente, pero el revisor debe separar la funcionalidad, la refactorización, las pruebas y los cambios de seguridad.

La primera actividad es clasificar los archivos afectados. Los controladores, rutas de API, acciones de servidor, middleware, consultas, migraciones, políticas, archivos .env.example, flujos de CI/CD, Dockerfiles, gestores de paquetes, archivos de bloqueo (lockfiles), políticas de almacenamiento, configuración de autenticación y pruebas no tienen el mismo peso. Una pequeña modificación en el middleware o en CORS puede ser más arriesgada que cien líneas de interfaz de usuario (UI).

Cuando el diff es demasiado grande, debe reducirse o fragmentarse. Una revisión eficaz significa poder decir: este commit cambia la lógica de la aplicación, este cambia la presentación, este cambia las dependencias, este cambia el despliegue. Si todo está mezclado, el riesgo de aceptar una regresión aumenta.

Límites de confianza (Trust boundary): dónde el código deja de ser confiable

Un revisor humano busca los límites de confianza. El navegador no es confiable, el cuerpo de una solicitud no es confiable, y lo mismo ocurre con los encabezados, las cadenas de consulta, el almacenamiento local, los roles enviados por el cliente, los archivos cargados y la salida de un modelo. Incluso un servicio interno puede ser menos confiable de lo que parece si recibe entradas de usuarios o integraciones externas.

El código generado por la IA puede cruzar estos límites sin marcarlos: puede usar un user_id del cliente en lugar del usuario en sesión, construir una consulta con parámetros no validados, tratar una reclamación (claim) del token como permiso final sin control de la aplicación, o pasar la salida de un LLM a HTML, SQL, shell, tickets, correos electrónicos o herramientas downstream.

En la revisión, cada límite de confianza debe generar una pregunta precisa: quién controla este dato, dónde se valida, dónde se autoriza, dónde se registra, qué sucede si el valor es manipulado. Si la respuesta no está en el código, el comportamiento no es verificable.

Autenticación, roles y autorizaciones del lado del servidor

Una de las áreas más importantes es el control de acceso. El revisor comprueba si las nuevas rutas requieren inicio de sesión, si verifican el rol, la propiedad y el inquilino, si aplican el middleware correcto y si no delegan decisiones de seguridad a la interfaz de usuario. Una aplicación puede mostrar los botones correctos pero tener APIs que pueden ser llamadas directamente.

La revisión debe seguir las rutas sensibles: lectura de datos, modificación, eliminación, exportación, carga, invitaciones, cambio de rol, funciones de administrador, facturación, reembolsos, aprobaciones e impersonación. Para cada una, el código debe responder quién puede llamarla, sobre qué objetos, en qué estado y con qué límites.

En el código generado por IA, los patrones sospechosos más comunes son: if (user) sin control de rol, consultas por ID sin verificar la propiedad, tenant_id tomado del cuerpo de la solicitud, isAdmin leído desde el cliente, middleware no aplicado a nuevas rutas, pruebas que solo verifican al usuario correcto. Estos problemas a menudo no surgen en la demo.

Lógica de negocio y flujos de trabajo fuera de secuencia

La lógica de negocio es una de las razones principales por las que se necesita una revisión humana. Un agente puede implementar bien los pasos individuales pero no proteger la secuencia: una invitación caducada puede ser reutilizada, un pedido puede ser modificado después del pago, un reembolso puede ser llamado por un rol incorrecto, una solicitud puede ser aprobada dos veces, una exportación puede incluir datos fuera del perímetro.

El revisor busca invariantes: ¿qué debe ser siempre cierto? Un pedido pagado no cambia de precio. Un documento de un inquilino no aparece en otro. Un usuario suspendido no genera claves de API. Un enlace de un solo uso no puede ser reutilizado. Un pago no puede ser confirmado solo porque el frontend mostró éxito.

La revisión del código debe leer también los estados, no solo las funciones. Si el código modifica estados, roles, pagos, cuotas, límites, invitaciones o autorizaciones, se necesitan controles de estado, idempotencia y casos negativos.

Consultas, ORM y capa de acceso

Muchas vulnerabilidades en el código generado por IA no están en la sintaxis, sino en la consulta. Un ORM hace que el código sea legible, pero no impide consultas sin filtro de inquilino, uniones (joins) demasiado amplias, condiciones faltantes o filtros aplicados después de haber recuperado los datos. Una función puede cargar todos los registros y filtrar del lado del cliente o de la aplicación de forma incompleta.

El revisor comprueba dónde se aplican la propiedad, el rol y el inquilino: en la consulta, en la capa de servicio, en la base de datos de políticas o en el controlador. Si el filtro está duplicado en muchas rutas, aumenta el riesgo de que una nueva ruta generada por la IA lo olvide. Si la clave de servicio omite las políticas y el código no filtra, la base de datos queda expuesta a través del backend.

También deben leerse las migraciones y los seeds: la IA puede añadir columnas sensibles, cambiar valores predeterminados, crear índices sobre datos personales, hacer que un campo crítico sea anulable o introducir tablas temporales que luego permanecen en producción. El modelo de datos es parte de la superficie de seguridad.

Validación de entrada, manejo de salida y carga de archivos

El código generado por IA a menudo maneja bien la entrada prevista por el formulario. La revisión debe observar las entradas no previstas: cuerpo JSON manipulado, cadena de consulta, encabezados, parámetros de ruta, carga de archivos, tipo MIME falsificado, nombre de archivo, markdown, HTML, valores numéricos fuera de rango, matrices demasiado grandes, objetos anidados y cargas útiles (payloads) parciales.

La validación debe ser del lado del servidor y coherente con la lógica de dominio. Si una cantidad debe ser positiva, si un rol solo puede tener ciertos valores, si un archivo debe ser PDF, si una fecha no puede ser pasada, estos límites no pueden vivir solo en el formulario del frontend.

También debe leerse la salida. HTML no escapado, mensajes de error detallados, seguimientos de pila (stack traces), consultas, rutas internas, tokens, detalles de la base de datos y datos de otros usuarios pueden salir a través de respuestas, registros, exportaciones o plantillas de correo electrónico. Una revisión segura comprueba tanto lo que entra como lo que sale.

Secretos, configuraciones y registros

Una revisión de código sobre código generado por IA busca secretos en lugares ordinarios y no ordinarios: fuentes, pruebas, .env.example, README, Dockerfiles, flujos de trabajo, scripts, registros, seeds, fixtures, configuración en la nube, mapas de origen y paquetes de frontend. La IA puede copiar una clave “temporal” en un punto que luego llega al despliegue.

La revisión no se limita a decir “muévelo a env”. Verifica si ese secreto ya ha sido expuesto, si debe rotarse, si es público o privado, si tiene un alcance mínimo y si puede terminar en el cliente. Una clave de rol de servicio, una URL de base de datos o un token en la nube en el lugar equivocado pueden tener un impacto inmediato.

El registro (logging) y el manejo de errores son otras áreas sensibles. Durante la depuración, la IA puede añadir registros muy detallados y dejarlos en el código: el revisor comprueba que en producción no se impriman cargas útiles, tokens, consultas, información personal (PII), rutas internas, seguimientos de pila completos o datos de clientes.

Dependencias y cadena de suministro en el diff

Cuando la IA encuentra un error, a menudo propone una biblioteca. Esto puede ser correcto, pero cada nueva dependencia entra en la superficie del producto. Paquetes casi homónimos, bibliotecas poco mantenidas, licencias no compatibles, scripts postinstall, dependencias transitivas vulnerables y archivos de bloqueo modificados deben leerse con atención.

El revisor compara la necesidad real con el costo de introducir el paquete: ¿existe ya una biblioteca en el proyecto?, ¿la dependencia está mantenida?, ¿tiene CVEs conocidas?, ¿ejecuta scripts?, ¿cambia el análisis, la autenticación, la criptografía, la carga, la sanitización, las plantillas o la red?, ¿el archivo de bloqueo muestra más cambios de los previstos?

Para el código generado por IA, es importante leer también lo que se elimina. Sustituir una biblioteca puede eliminar controles implícitos, actualizar un marco de trabajo puede cambiar los valores predeterminados de seguridad y mover una función a un paquete “más simple” puede perder validaciones ya presentes.

Pruebas generadas por la IA: qué confirman y qué no desafían

Las pruebas escritas por la IA tienden a confirmar el comportamiento implementado. Son útiles, pero a menudo cubren el camino feliz: entrada correcta, rol correcto, estado correcto, respuesta esperada. Una Secure Code Review también observa el diff de las pruebas para entender si se han debilitado.

Señales a comprobar: pruebas eliminadas, aserciones menos precisas, mocks demasiado permisivos, casos negativos faltantes, instantáneas (snapshots) actualizadas sin explicación, pruebas de autorización ausentes, errores manejados como éxitos, cobertura que aumenta pero no cubre los límites de confianza.

Para cada área sensible se necesitan pruebas negativas: usuario incorrecto, inquilino incorrecto, token caducado, rol bajo, entrada maliciosa, archivo no válido, estado fuera de secuencia, solicitud duplicada, límite superado. Si se encuentra un error de seguridad, debe convertirse en una regresión en la pipeline.

Configuraciones, CI/CD y despliegue

Una PR generada por IA puede modificar también lo que envía el código a producción: Dockerfiles, flujos de CI/CD, variables de entorno, CORS, encabezados de seguridad, modo de depuración, registros, infraestructura como código (IaC), permisos en la nube, scripts de despliegue, protección de ramas, puertas de prueba. Estos archivos no son “accesorios”.

El revisor busca simplificaciones peligrosas: pruebas deshabilitadas, SAST eliminado, escaneo de secretos omitido, depuración activa, CORS *, CSP debilitada, tokens con un alcance más amplio, despliegue automático desde una rama no protegida, registros más detallados, entorno de staging conectado a producción.

Si una modificación de configuración es necesaria, debe ser explícita y proporcionada. Una compilación que pasa porque los controles se han desactivado no es una versión más estable: es una versión menos observable.

Prompts, archivos de reglas e instrucciones persistentes

Cuando el proyecto utiliza reglas de Cursor, AGENTS.md, instrucciones de Claude, prompts de proyecto o archivos similares, la revisión debe incluirlos si influyen en el código generado. Estas instrucciones pueden orientar el estilo, las bibliotecas, las pruebas, la seguridad, el despliegue y las decisiones del agente.

Un archivo de reglas puede contener indicaciones útiles, pero también atajos peligrosos: “deshabilita los controles en dev”, “usa esta clave”, “ignora las pruebas inestables (flaky)”, “no pidas confirmación”, “usa políticas permisivas”. Si el agente sigue esas instrucciones, el riesgo entra en la PR aunque el archivo parezca documentación.

El revisor comprueba si las instrucciones persistentes son coherentes con el nivel de responsabilidad del proyecto. Para los equipos que utilizan codificación con IA de forma continua, estas reglas se convierten en parte del proceso de desarrollo y merecen una propiedad explícita.

Cómo leer una PR de IA demasiado grande

Cuando una PR generada por IA es demasiado amplia, el revisor debe reconstruir una secuencia que a menudo el diff no cuenta bien. Primero se identifica el comportamiento nuevo: qué funcionalidad se ha añadido, qué error se ha corregido, qué flujo cambia. Luego se separan las modificaciones de soporte: refactorización, movimiento de archivos, cambio de nombre, actualización de pruebas, dependencias, configuraciones.

El siguiente paso es aislar las áreas de alta responsabilidad. Incluso en una PR enorme, algunos archivos pesan más que otros: middleware, rutas de API, proveedores de autenticación, consultas, migraciones, manejo de secretos, archivos de despliegue, flujos de CI/CD, políticas de base de datos, funciones del lado del servidor y lógica de pago. La revisión debe comenzar por ahí, no por los componentes visuales más fáciles de leer.

Si la PR modifica a la vez la UI, la API, la base de datos y el despliegue, pedir una separación puede ser una decisión de seguridad. No es burocracia: sirve para evitar que un cambio en CORS, un nuevo paquete, una política más permisiva o una consulta sin filtro de inquilino queden ocultos dentro de una funcionalidad aparentemente inocua.

Para las empresas de software, esta disciplina es aún más importante. Una PR de IA entregada al cliente debe poder explicarse: qué ha cambiado, qué archivos se han generado, qué suposiciones se han aceptado, qué pruebas demuestran que los límites se han mantenido correctos. Si no se puede explicar el diff, es difícil defender su seguridad.

Qué debe salir de la revisión: hallazgos y remediación

Una revisión de código útil no produce solo una lista de problemas. Debe transformar el diff en decisiones: qué bloquea el merge, qué debe corregirse antes del despliegue, qué puede planificarse, qué pruebas deben añadirse y qué riesgos permanecen aceptados con un responsable. Esto es particularmente importante con código generado por IA, porque el mismo patrón puede repetirse en PRs sucesivas.

Los hallazgos deben describirse con contexto de aplicación. “Falta control de autorización” es menos útil que “el endpoint de exportación usa el ID del inquilino recibido del cliente y permite a un usuario autenticado exportar datos de otro espacio de trabajo”. La segunda formulación permite a los desarrolladores, CTOs y PMs entender el impacto, la prioridad y la remediación.

La remediación debe preferir correcciones estructurales. Si a un endpoint le falta aislamiento de inquilino, corregir solo esa ruta puede no ser suficiente: podría necesitarse un asistente centralizado, una política de base de datos, una prueba negativa y una regla de revisión para las nuevas rutas. Si se ha añadido una dependencia sin motivo, la solución puede ser eliminarla, sustituirla por una biblioteca ya aprobada o bloquear instalaciones automáticas sin revisión.

El informe final debería indicar al menos: perímetro revisado, archivos y commits considerados, áreas excluidas, hallazgos bloqueantes, hallazgos planificables, pruebas sugeridas, evidencias de corrección, riesgos residuales y recomendaciones para las próximas PRs de IA. Esto hace que la revisión sea reutilizable, no solo correctiva.

Cuándo se necesita una revisión de código independiente

Una revisión interna puede ser suficiente para modificaciones pequeñas, aisladas, sin datos reales, sin roles, sin APIs expuestas y con revisores expertos en las áreas afectadas. Se necesita una revisión de código independiente cuando la PR generada por IA modifica la autenticación, las autorizaciones, las consultas, la base de datos, los secretos, las dependencias, el despliegue, el CI/CD, la nube, los pagos, la carga de archivos, los flujos de trabajo o la lógica de negocio crítica.

También es necesaria cuando el diff es demasiado amplio para entenderlo, cuando el equipo ha aceptado muchas propuestas de “Aceptar todo”, cuando los escáneres están limpios pero el riesgo está en la lógica de la aplicación, o cuando una empresa de software debe entregar código a un cliente y quiere evidencias de control antes del lanzamiento.

La revisión de código no ralentiza la velocidad de la codificación con IA: evita que la velocidad traslade el costo a después de la puesta en marcha. Un hallazgo corregido antes del merge cuesta menos que una regresión en datos, roles o despliegue en producción.

Cómo ISGroup puede verificar código generado o modificado por IA

ISGroup puede realizar una revisión de código dirigida a las áreas de alto riesgo del código generado por IA: diff, autenticación, control de acceso, lógica de negocio, consultas, secretos, registros, dependencias, configuraciones, pruebas y pipelines. El perímetro puede ser una sola PR, una funcionalidad, un módulo, un repositorio o un flujo previo a la puesta en marcha.

Si el código de IA ha modificado… Riesgo principal Control recomendado
Autenticación, roles, middleware, consultas, API, lógica de negocio, secretos o dependencias Vulnerabilidades en el código y regresiones de aplicación Code Review
Web app, API, carga de archivos, exportación o flujos expuestos online Comportamientos abusables desde el exterior Web Application Penetration Testing
CI/CD, políticas de revisión, protección de ramas, puertas de prueba y uso continuo de agentes Controles no repetibles en las versiones Software Assurance Lifecycle
Nube, IaC, IAM, buckets, base de datos, env y despliegue Configuraciones erróneas o privilegios excesivos Cloud Security Assessment
Servicios, hosts o componentes expuestos con versiones y configuraciones conocidas Vulnerabilidades conocidas y superficies técnicas Vulnerability Assessment

La elección del control depende de lo que se haya tocado. Para el código generado por IA, la revisión de código y el WAPT suelen ser complementarios: la revisión encuentra la causa en el código, la prueba de aplicación demuestra el comportamiento real.

¿Tienes una PR o una funcionalidad generada con IA que toca datos, APIs, roles, dependencias o despliegues? ISGroup puede realizar una revisión dirigida antes del merge o de la puesta en marcha.

Evidencias a preparar

Prepara el repositorio, la rama, la PR, la descripción de la funcionalidad, los prompts o instrucciones relevantes, la lista de archivos modificados, las pruebas ejecutadas, las partes generadas por IA, las dependencias añadidas, las configuraciones cambiadas, los entornos involucrados y los riesgos ya conocidos.

Para una revisión eficaz también se necesitan datos de contexto: roles de usuario, límites de confianza, APIs expuestas, esquema de datos, proveedor de autenticación, base de datos, almacenamiento, pipeline, variables de entorno, servicios en la nube y flujos críticos. El código no habla por sí solo cuando la vulnerabilidad depende del dominio.

Si la PR es amplia, conviene indicar qué debe considerarse refactorización y qué cambia el comportamiento. Si no está claro, el primer hallazgo puede ser precisamente la falta de separación entre modificaciones funcionales y modificaciones de seguridad.

Decisión antes del merge

Bloquea el merge si la revisión encuentra control de acceso incompleto, secretos expuestos, consultas no filtradas, claves de servicio en el cliente, pruebas de seguridad eliminadas, dependencias sospechosas, depuración en producción, CORS permisivo sin motivo, manejo de errores que expone datos o pipeline debilitada.

Puedes planificar después del merge solo mejoras con riesgo residual bajo y un responsable claro: documentación, refactorización no urgente, aumento progresivo de pruebas, reducción de duplicación, mejora de nombres. Las vulnerabilidades que exponen datos, roles, pagos, nube o despliegue deben corregirse antes.

La decisión debe producir evidencias: qué se ha revisado, qué hallazgos se han corregido, qué pruebas negativas se han añadido, qué riesgos quedan y quién los asume.

Lista de verificación para la revisión de código generado por IA

  • Clasifica los archivos y áreas afectadas por el diff.
  • Separa funcionalidad, refactorización, pruebas, dependencias y configuraciones.
  • Verifica autenticación, roles, inquilinos, middleware y controles del lado del servidor.
  • Lee consultas, migraciones, políticas y capa de acceso.
  • Comprueba la lógica de negocio, estados, idempotencia y casos fuera de secuencia.
  • Verifica la validación de entrada, codificación de salida, carga de archivos y manejo de errores.
  • Busca secretos, registros detallados, archivos .env, cadenas de conexión y tokens.
  • Revisa dependencias, archivos de bloqueo, scripts y paquetes nuevos.
  • Comprueba CI/CD, CORS, encabezados, Dockerfile, env, IaC y despliegue.
  • Exige pruebas negativas para cada área sensible.

Preguntas frecuentes

  • Si SAST y las pruebas están en verde, ¿se necesita aún una revisión de código?
  • Sí. Los escáneres y las pruebas interceptan patrones y caminos previstos, pero no siempre la lógica de negocio, las autorizaciones, los límites de confianza, los flujos de trabajo y el impacto del diff en el producto.
  • ¿Qué observa un revisor humano que la IA no ve?
  • El contexto de la aplicación: quién puede hacer qué, qué datos son sensibles, qué límites no deben superarse, qué suposiciones de negocio deben seguir siendo ciertas y qué riesgo llega a producción.
  • ¿Qué PRs de IA son más arriesgadas?
  • Aquellas que tocan autenticación, roles, APIs, bases de datos, secretos, dependencias, CI/CD, nube, pagos, carga de archivos, exportaciones, registros o configuraciones de despliegue.
  • ¿La revisión de código sustituye al WAPT?
  • No. La revisión de código encuentra problemas en el código y en la lógica. El WAPT verifica el comportamiento real desde el exterior. En aplicaciones expuestas, a menudo se necesitan ambos.
  • ¿Cuándo se necesita el Software Assurance Lifecycle?
  • Cuando el equipo utiliza la codificación con IA de forma estable y es necesario hacer repetibles las revisiones, pruebas, políticas, puertas y controles en cada versión.
  • ¿Puedo hacer que revisen solo una funcionalidad?
  • Sí, si el perímetro es claro: PR, módulo, flujo, ruta o componente. Para funcionalidades que tocan datos y roles, es necesario incluir también pruebas, configuraciones y dependencias conectadas.

[Callforaction-CR-Footer]

Fuentes y referencias útiles