El código generado por IA puede compilar, pasar una prueba sencilla y aun así ser una mala decisión de seguridad. La apariencia ordenada de una función no te dice qué datos expone, qué permisos necesita, qué dependencia introduce ni qué ocurre cuando un usuario controla la entrada. Revisar cada línea sin entender esas consecuencias produce una sensación de control, no necesariamente un programa seguro.
La revisión empieza con una pregunta distinta: ¿qué puede exponer, alterar, ejecutar o permitir este código? Después puedes leer la implementación con más precisión. El OWASP Top 10 se presenta como un documento de concienciación para los riesgos más críticos de las aplicaciones web y como un punto de partida para construir prácticas de desarrollo más seguras [referencia oficial de OWASP]. No es una garantía ni una auditoría completa, pero ofrece categorías que ayudan a mirar más allá del caso ideal.
Empieza por el daño posible, no por el estilo del código
Antes de ejecutar una sugerencia, describe el pequeño sistema en el que vivirá. ¿Qué entrada controla el usuario? ¿Qué información es confidencial? ¿Qué recursos puede leer o modificar el proceso? ¿Qué servicio externo recibe datos? ¿Qué ocurre si la dependencia no está disponible?
| Pregunta | Riesgo que ayuda a descubrir | Prueba inicial |
|---|---|---|
| ¿Qué datos entran desde fuera? | Inyección, datos malformados y validación insuficiente | Usar entradas vacías, largas, inesperadas y manipuladas |
| ¿Qué secretos aparecen? | Exposición de claves, tokens y datos personales | Buscar secretos en código, logs, errores y repositorios |
| ¿Qué puede hacer el proceso? | Exceso de permisos y acciones no autorizadas | Ejecutar con el usuario y permisos mínimos |
| ¿Qué componentes añade? | Dependencias inexistentes, vulnerables o abandonadas | Comprobar paquete, versión, fuente y lockfile |
Esta tabla no convierte la seguridad en un formulario mecánico. Su función es impedir que una respuesta con nombres de variables elegantes desvíe tu atención de la superficie real de ataque.
Trata la sugerencia como código de un tercero
Una recomendación de IA no conoce automáticamente las reglas de tu aplicación, tus datos, tu modelo de amenazas ni la versión exacta de cada biblioteca. El resultado puede contener supuestos razonables para otro proyecto y peligrosos para el tuyo. El GitHub Docs describe el uso responsable de Copilot a partir de comprender los propósitos, capacidades y limitaciones de cada función [documentación oficial de uso responsable]. La consecuencia práctica es sencilla: la revisión humana no es una etapa opcional añadida después de generar. El marco SSDF del NIST para software desarrollado con IA generativa complementa las prácticas generales de desarrollo seguro con consideraciones específicas del uso de estos modelos. No reemplaza las pruebas del proyecto, pero refuerza la idea de que la generación debe entrar en un proceso controlado.
Lee la sugerencia como leerías un fragmento copiado de un foro: identifica la fuente, comprueba la versión de la API, ejecuta pruebas en un entorno aislado y pregunta qué información pudo haber quedado fuera del contexto. No necesitas desconfiar de cada carácter, pero sí evitar que el hecho de que el texto sea fluido se convierta en un atajo de confianza.
También registra qué cambió. Si una herramienta generó una función de autenticación, una consulta a base de datos o un script que ejecuta comandos, conserva la revisión en un commit separado. Esa separación permite revertir, comparar y explicar la decisión cuando aparezca un fallo.
Los secretos no pertenecen al código ni a sus ejemplos
Contraseñas, claves de API, tokens de sesión y certificados no deben aparecer como valores literales en un archivo que pueda terminar en un repositorio, una captura de pantalla o un registro. El problema no desaparece porque el proyecto sea personal: una clave reutilizada puede dar acceso a un servicio, generar costes o exponer información de otras personas.
# Mejor: leer el secreto desde el entorno
import os
api_key = os.environ["PAYMENTS_API_KEY"]
Pero mover una cadena a una variable de entorno no completa la revisión. Comprueba que el secreto no se imprima en mensajes de depuración, que el archivo local esté fuera del repositorio, que el sistema de despliegue lo inyecte de forma segura y que una excepción no lo incluya en su traceback. Si una clave ya fue comprometida, no basta con borrarla del último commit: debes revocarla y sustituirla.
La IA puede inventar valores de ejemplo que parecen funcionales o copiar un patrón inseguro si le pides “un código completo” sin explicar cómo se administran las credenciales. Pídele explícitamente que use variables de entorno, que no genere secretos reales y que marque las decisiones de configuración que todavía debes completar. Nuestra guía sobre los límites de la IA en programación ayuda a identificar otros casos en los que la herramienta puede sonar segura sin conocer tu contexto.
Verifica cada dependencia antes de instalarla
El código generado puede sugerir una biblioteca con un nombre plausible, una API antigua o una versión que ya no corresponde a la documentación actual. Instalar sin comprobar transforma una respuesta de texto en una modificación del sistema. Busca el paquete en el registro correcto, revisa su documentación, confirma que resuelve el problema que tienes y comprueba si la versión es compatible con tu proyecto.
La revisión también debe preguntarse si necesitas una dependencia nueva. Una función corta de la biblioteca estándar o una API nativa puede ser más fácil de mantener que un paquete para resolver una tarea pequeña. Cuando sí necesitas un paquete, usa el lockfile y las herramientas de auditoría de tu ecosistema; no pegues una lista de dependencias en el proyecto solo porque la IA la generó.
Observa especialmente scripts de instalación, permisos amplios, paquetes con nombres casi idénticos y dependencias transitivas que no reconoces. La seguridad no depende solo de que el paquete principal tenga muchas descargas; depende de qué código se ejecuta y con qué permisos cuando lo incorporas.
La entrada del usuario debe tratarse como una amenaza
Un formulario, un parámetro de URL, un archivo subido o un mensaje recibido por una API son datos no confiables hasta que tu programa los valida y los usa de manera segura. Una validación que comprueba únicamente que el campo no está vacío no evita que la entrada contenga comandos, consultas o estructuras inesperadas.
En una consulta SQL, por ejemplo, concatena datos del usuario y código produce una separación frágil entre ambos. Usa los parámetros que proporciona el controlador de base de datos y valida el tipo, el tamaño y el rango que el negocio acepta. En HTML, escapa o sanea el contenido según el contexto en el que se insertará. En una ruta de archivo, impide que una entrada construya un camino fuera del directorio permitido.
# Concepto: separar la consulta de los valores
cursor.execute(
"SELECT id, name FROM users WHERE email = ?",
(email_proporcionado_por_usuario,)
)
No copies este ejemplo sin revisar el controlador concreto: algunos usan %s, otros ? y otros una API distinta. La idea importante es que el dato se entregue como parámetro, no que se convierta en parte del texto de la consulta. Para estudiar por qué los errores de entrada importan, puedes consultar también nuestras guías sobre tareas donde la IA es más útil y manejo de excepciones en Python.
Revisa permisos y efectos secundarios
Un fragmento puede ser correcto en aislamiento y peligroso por lo que está autorizado a hacer. Pregunta si necesita leer todo el sistema de archivos, ejecutar un proceso, acceder a la red, modificar una base de datos o actuar con una cuenta administrativa. Reduce el alcance a la operación concreta y prueba con un usuario sin privilegios cuando sea posible.
La IA suele optimizar para que el ejemplo “funcione” y puede sugerir permisos amplios para evitar errores de configuración. Esa comodidad tiene un coste. Un script que borra archivos, instala paquetes o publica datos debería mostrar claramente la acción, pedir confirmación en el nivel adecuado y tener una ruta de reversión. Si no puedes explicar qué efecto secundario produce una línea, todavía no está lista para entrar en tu proyecto.
Separa las operaciones de lectura y escritura cuando puedas. Una función que calcula una ruta no debería borrar archivos como efecto oculto; una función que prepara una consulta no debería enviarla a producción sin una capa explícita de autorización. Las fronteras visibles hacen que la revisión y las pruebas sean más sencillas.
Prueba con casos que contradicen el ejemplo
El caso ideal es el ejemplo que la IA ya conoce. Para revisar seguridad, construye casos que intenten romper los supuestos: cadenas vacías, caracteres especiales, tamaños extremos, tipos equivocados, valores duplicados, permisos insuficientes, respuestas incompletas y servicios que dejan de responder.
Escribe primero qué debería ocurrir y después ejecuta la prueba. Un programa seguro no tiene que aceptar cualquier entrada; tiene que rechazarla de forma controlada, sin filtrar secretos ni dejar el sistema en un estado parcial. Comprueba también el log: el mensaje debe ayudar a diagnosticar, pero no revelar tokens, consultas completas ni datos personales.
Cuando la IA proponga “manejar todos los errores” con un bloque amplio, reemplázalo por excepciones y respuestas que puedas explicar. Un error de validación puede devolver una respuesta para el usuario; un fallo de conexión puede activar un reintento limitado; un problema de permisos puede detener la operación y solicitar configuración. Esconder todo detrás de un mensaje genérico elimina señales útiles.
Un flujo de revisión de quince minutos
- Describe qué datos recibe el código y quién los controla.
- Marca secretos, llamadas externas, escrituras y comandos ejecutables.
- Confirma cada paquete, versión, documentación y permiso requerido.
- Prueba entradas vacías, grandes, malformadas y deliberadamente adversas.
- Revisa errores y logs para verificar que no revelan información sensible.
- Compara el resultado con una fuente oficial del lenguaje o de la biblioteca.
- Guarda el cambio aislado, documenta lo que revisaste y deja una forma de revertirlo.
El flujo es pequeño a propósito. No pretende certificar una aplicación completa; evita que un fragmento generado por IA pase directamente de la conversación al repositorio. En proyectos reales, las revisiones de dependencias, autenticación y autorización necesitan controles adicionales, herramientas automatizadas y personas con experiencia en seguridad.
Preguntas que no debes responder con un “parece correcto”
¿El código generado por IA es inseguro por definición?
No. Puede ser útil y correcto, pero no conoce automáticamente tus requisitos, límites, datos ni modelo de amenazas. Debe pasar por las mismas pruebas, revisión y controles que el código obtenido de cualquier otra fuente externa.
¿Basta con no copiar claves directamente en el código?
No. También debes revisar logs, errores, repositorios, variables de despliegue, permisos y rotación. Una clave expuesta anteriormente puede necesitar revocación aunque ya no aparezca en el archivo actual.
¿Cómo reviso una dependencia que la IA me recomienda?
Comprueba que exista en el registro correcto, que su documentación coincida con el código, que la versión sea compatible y que no introduzca permisos o componentes innecesarios. Si la tarea es pequeña, evalúa si la biblioteca estándar o una API nativa resuelve el problema.
¿Probar con un caso normal demuestra que el código es seguro?
No. El caso normal solo confirma un camino. Agrega entradas adversas, permisos insuficientes, respuestas incompletas y fallos de red para verificar cómo el sistema rechaza y registra condiciones inesperadas.
La revisión de seguridad no empieza preguntando si el código se ve profesional. Empieza preguntando qué puede hacer cuando el usuario, la dependencia, la red o el sistema no se comportan como en el ejemplo. La IA puede acelerar la escritura, pero la confianza debe ganarse con límites, pruebas y una explicación que resista esas preguntas.

Martin Rojas escribe sobre tecnología, programación y desarrollo web. En Skydutz Academy comparte explicaciones prácticas sobre herramientas digitales, conceptos de programación y recursos para aprender de forma progresiva. Su objetivo es hacer que los temas técnicos sean más claros, útiles y accesibles para lectores de distintos niveles.
