Saltar al contenido

Guía

Checklist práctica para revisar código generado por IA antes de hacer merge

Diez cosas que revisar en el código que escribió un asistente: de dependencias inventadas y controles de acceso solo en el navegador a tests que no comprueban nada.

· 9 min de lectura · Por el equipo de vetkit

Un robot presenta orgulloso una ventana de código mientras un desarrollador marca elementos en una gran checklist sujeta a un portapapeles.Un robot presenta orgulloso una ventana de código mientras un desarrollador marca elementos en una gran checklist sujeta a un portapapeles.

El código de un asistente suele compilar, se lee bien y hace más o menos lo que pediste. Precisamente por eso es fácil darle el visto bueno sin mirarlo. Los errores rara vez son de sintaxis. Son decisiones que el modelo tomó en silencio: una dependencia que supuso que existía, un control de permisos que puso en el lugar equivocado, un error que decidió ignorar.

Esta es la checklist que usamos cuando revisamos cambios hechos con ayuda de IA. No va de si el código es elegante. Va del puñado de problemas que acaban convirtiéndose en incidentes.

Por qué el código de IA necesita otra revisión

Cuando un compañero escribe código, normalmente puedes fiarte de las partes que no menciona. Conocía el código, probó el cambio en local y te habría dicho si algo estaba sin terminar. Un modelo no tiene nada de ese contexto a menos que se lo des, y tiende a rellenar los huecos con algo verosímil en lugar de con una pregunta. Así que la revisión pasa de «¿está bien escrito?» a «¿qué ha dado por supuesto?».

1. Dependencias

Revisa cada paquete que añade el cambio. ¿Existe en el registro? ¿Es el paquete que recomienda la documentación oficial o uno con un nombre parecido? ¿Se publicó la semana pasada? Los modelos a veces inventan nombres de paquetes, y algunos de esos nombres acaban registrados por atacantes. Nuestra guía sobre slopsquatting explica cómo revisar un paquete en un minuto.

Fíjate también en las versiones. Una versión fijada a algo que nunca se publicó romperá la próxima instalación desde cero, y una dependencia sin versión fijada significa que el código que revisaste no es el código que se ejecuta.

2. Secretos y variables públicas

Busca en el diff claves, tokens y contraseñas, también en los archivos de test y en los ejemplos. Luego revisa las variables de entorno con prefijos públicos como VITE_, NEXT_PUBLIC_ o EXPO_PUBLIC_. Todo lo que lleve esos prefijos se copia en el bundle del navegador durante el build. Un asistente puede renombrar un secreto con uno de ellos para que una funcionalidad funcione en el navegador. Esta guía repasa la versión de ese error con la API key de un LLM.

3. Dónde se comprueba el acceso

Encuentra la línea que decide si el usuario actual puede hacer esto. Si está en un componente de React, en un guard de ruta o en un botón oculto, es una cuestión de experiencia de usuario, no de seguridad. Cualquiera puede llamar directamente a tu API. La comprobación tiene que hacerse en el servidor, en cada petición, contra el recurso al que se accede: no solo «¿ha iniciado sesión este usuario?», sino «¿es este usuario el dueño de esta factura?».

Vigila las rutas de API nuevas sin ningún middleware de autenticación y los backends como Supabase o Firebase en los que la base de datos es accesible desde el navegador. Ahí, la protección son las propias reglas de la base de datos. Una tabla de Supabase sin seguridad a nivel de fila está abierta a cualquiera que tenga tu anon key pública.

4. Entrada no confiable

Sigue la entrada del usuario desde donde entra hasta donde se usa. El SQL construido concatenando cadenas, los comandos de shell montados a partir de campos de la petición, las rutas de archivo tomadas de parámetros de consulta, el HTML renderizado a partir de contenido de usuarios y las URL que se solicitan en nombre de un usuario son los patrones clásicos de inyección, path traversal, XSS y SSRF. Los asistentes todavía los producen, sobre todo cuando el código de alrededor ya hace algo parecido.

text
// Looks harmless, is an injectiondb.query(`SELECT * FROM users WHERE email = '${req.query.email}'`); // Parameterizeddb.query('SELECT * FROM users WHERE email = $1', [req.query.email]);

5. Código a medio terminar

Las generaciones largas a veces se quedan cortas. Busca marcadores de posición en el cambio: TODO, «implement later», «rest of the code here», funciones que devuelven datos de ejemplo escritos a mano, credenciales de prueba y archivos con nombres como utils copy.ts. Busca también supresiones generalizadas como // @ts-ignore, eslint-disable al principio de un archivo o any usado para silenciar al comprobador de tipos. A menudo esconden justo el problema que el modelo no supo resolver.

6. Manejo de errores

Un bloque catch que registra el error y sigue adelante, o que lo captura todo y devuelve un resultado vacío, convierte un fallo ruidoso en una pérdida silenciosa de datos. Pregúntate qué debería pasar cuando esta llamada falla y si el código hace eso. Desconfía de los reintentos sin límite y de los errores que se convierten en respuestas de éxito.

7. Tests

Merece la pena leer los tests generados línea a línea. Problemas habituales: tests que nunca comprueban nada, tests que hacen mock de la misma función que están probando, aserciones que solo comprueban que se llamó a una función y .only o .skip olvidados. Una suite de tests que pasa no es evidencia hasta que sabes que puede fallar. Rompe el código a propósito una vez y comprueba si algún test lo detecta.

8. Timeouts y llamadas bloqueantes

Las llamadas HTTP salientes sin timeout son un incidente en producción esperando a que una dependencia vaya lenta. Muchos clientes populares esperan indefinidamente por defecto, entre ellos requests de Python y http.DefaultClient de Go. En Node.js, las operaciones de archivo síncronas o el hash de contraseñas dentro de un manejador de peticiones bloquean todas las demás peticiones de ese proceso. Rara vez aparecen en las pruebas locales porque tu portátil y tus dependencias son rápidos y están desocupados.

9. Acceso a datos

Busca consultas dentro de bucles (el problema N+1), endpoints de listado que devuelven todas las filas sin paginación y clientes de base de datos que se crean en cada petición en lugar de compartirse. Revisa también las migraciones con cuidado: una sincronización del esquema que se ejecuta al arrancar, o una migración que elimina y vuelve a crear una tabla, puede borrar datos de producción en el siguiente despliegue.

10. Funcionalidades con LLM

Si el cambio llama a un modelo, trata su salida como entrada no confiable. Nunca debe ejecutarse, concatenarse en SQL ni renderizarse como HTML sin procesar. Comprueba que la API key se queda en el servidor, que la ruta que llama al modelo exige un usuario con sesión iniciada y tiene rate limiting, y que la longitud de la salida está limitada. Si un agente tiene herramientas, comprueba qué pueden hacer esas herramientas y si el texto de documentos o páginas web puede dirigirlas.

Conviértelo en rutina

Diez comprobaciones por pull request son muchas para hacerlas a mano, y la gracia de una checklist es dejar de depender de la memoria. La mayoría de estos puntos se pueden automatizar, al menos en parte. Así tu atención queda libre para lo que a las herramientas se les da mal, como saber si el cambio hace lo que el producto realmente necesita.

vetkit agrupa estos checks en suites: seguridad (secretos, dependencias vulnerables, vulnerabilidades en el código, configuración de infraestructura), calidad del código, sostenibilidad, riesgos del código generado por IA (paquetes inventados, código a medio terminar, trampas de las plataformas de aplicaciones, seguridad de LLM y agentes) y preparación para producción (timeouts, llamadas bloqueantes, uso de la base de datos, aspectos operativos básicos). Lee tu código sin instalarlo, compilarlo ni ejecutarlo, e informa de lo que encuentra con el archivo, la línea y una corrección sugerida. Como cualquier análisis estático, puede pasar cosas por alto y puede equivocarse, así que sirve de apoyo a una revisión en lugar de sustituirla.

Solicita acceso anticipado

Cuéntanos un poco sobre tu equipo y los repositorios que quieres auditar. Incorporamos equipos en pequeños grupos y te responderemos por correo electrónico.

Solo usamos estos datos para responder a tu solicitud. Política de privacidad