
Python es uno de los lenguajes más usados para crear APIs, automatizaciones, aplicaciones web, scripts empresariales, ciencia de datos e inteligencia artificial. Pero escribir código que “funciona” no significa escribir código seguro. Una API puede responder rápido y aun así exponer datos, aceptar entradas peligrosas, filtrar secretos, ejecutar comandos indebidos o depender de paquetes vulnerables.
Esta guía resume las prácticas esenciales para aprender Python seguro desde cero, con enfoque en aplicaciones y APIs. La idea no es volver complejo el desarrollo, sino incorporar seguridad desde el primer archivo del proyecto: dependencias controladas, validación de entradas, autenticación, autorización, manejo correcto de secretos, logs útiles, pruebas automatizadas y revisión continua.
Idea central: Python no es inseguro por sí mismo. Las vulnerabilidades aparecen cuando se confía demasiado en entradas externas, se instalan dependencias sin control, se exponen APIs sin autorización o se ejecutan datos como si fueran código.
1. Empieza con un entorno limpio y dependencias controladas
Todo proyecto Python debería iniciar con un entorno virtual. Esto evita mezclar librerías del sistema con dependencias del proyecto y permite reproducir versiones. En proyectos profesionales, además conviene fijar versiones, revisar vulnerabilidades y documentar cada paquete que se instala.
Para auditar dependencias, pip-audit es una herramienta oficial del ecosistema PyPA que revisa entornos, archivos de requisitos y árboles de dependencias contra bases de datos de vulnerabilidades conocidas. También existe Bandit, un analizador estático diseñado para encontrar problemas comunes de seguridad en código Python.
2. Valida siempre las entradas
Una regla básica de seguridad es no confiar en ningún dato externo. Todo lo que llega por formularios, JSON, cabeceras HTTP, cookies, parámetros de URL, archivos, colas, webhooks o APIs externas debe validarse antes de usarse.
En APIs modernas con FastAPI, el uso de modelos de datos ayuda a validar tipos, estructuras y campos obligatorios. En Django y Flask también se pueden usar formularios, validadores y esquemas externos. Lo importante es validar en el servidor, aunque el frontend ya valide.
| Entrada | Qué validar |
|---|---|
| Texto | Longitud, formato, caracteres permitidos y uso esperado. |
| Números | Rango mínimo, máximo, tipo entero o decimal. |
| Archivos | Tamaño, extensión, tipo MIME, nombre seguro y ubicación permitida. |
| JSON | Campos permitidos, tipos correctos y ausencia de propiedades inesperadas. |
3. Evita SQL injection con consultas parametrizadas
Una de las fallas clásicas en aplicaciones web es construir consultas SQL concatenando texto con datos del usuario. La forma correcta es usar consultas parametrizadas, ORM o abstracciones que separen datos de instrucciones SQL.
SQLAlchemy explica que los parámetros enlazados son manejados por el DBAPI y advierte que saltarse ese mecanismo es una de las fallas de seguridad más explotadas en aplicaciones modernas.
4. Protege autenticación y autorización en APIs
En APIs, no basta con saber quién es el usuario; también hay que comprobar qué puede hacer. OWASP API Security Top 10 2023 coloca fallas como Broken Object Level Authorization, Broken Authentication y Broken Object Property Level Authorization entre los riesgos principales de APIs.
En términos simples: cada endpoint debe validar identidad, permisos, propiedad del recurso y acciones permitidas. Un usuario autenticado no debería poder ver, modificar o borrar recursos de otro usuario solo cambiando un identificador.
Regla para APIs: autenticar responde “quién eres”; autorizar responde “qué puedes hacer”. Las dos validaciones deben aplicarse en cada operación sensible.
5. Usa tokens y secretos de forma segura
Python incluye el módulo secrets, diseñado para generar tokens seguros para casos como recuperación de contraseña, URLs difíciles de adivinar y credenciales temporales. La recomendación es no usar random para tokens de seguridad.
Las claves de API, contraseñas de base de datos, llaves privadas y secretos JWT no deben estar escritos dentro del código. Deben cargarse desde variables de entorno, gestores de secretos o configuración segura del entorno de despliegue.
6. No uses pickle con datos no confiables
pickle es útil para serializar objetos Python, pero no debe usarse para cargar datos no confiables. La documentación oficial de Python advierte que nunca se debe deserializar información que provenga de una fuente no confiable o que pueda haber sido manipulada.
Para APIs, configuraciones, integraciones y transferencia de datos, normalmente es más seguro usar formatos como JSON con validación estricta de esquema. En ciencia de datos e IA, los archivos serializados también deben tratarse con cuidado, especialmente si vienen de terceros.
Advertencia: no cargues archivos pickle descargados de Internet, recibidos por correo o subidos por usuarios. Si necesitas intercambiar datos, usa formatos más controlables y validables.
7. Cuidado con subprocess y comandos del sistema
Muchas aplicaciones Python necesitan llamar comandos del sistema. El riesgo aparece cuando se mezcla entrada del usuario con comandos shell. La documentación oficial de Python incluye advertencias específicas sobre el uso de subprocess y recomienda leer las consideraciones de seguridad antes de usar shell=True.
La práctica recomendada es pasar argumentos como lista, evitar shell=True, validar entradas y usar listas permitidas cuando el usuario pueda elegir una acción.
8. Configura CORS, cookies y CSRF correctamente
En aplicaciones web y APIs consumidas desde navegador, CORS mal configurado puede exponer datos o permitir orígenes no confiables. OWASP Top 10 menciona la mala configuración de CORS como ejemplo dentro de fallas de control de acceso.
Flask documenta consideraciones de seguridad relacionadas con XSS, CSRF, cookies, cabeceras de seguridad y límites de recursos. Django, por su parte, incluye protecciones contra XSS y CSRF siempre que se usen correctamente sus mecanismos.
- No uses * en CORS si manejas credenciales.
- Define orígenes permitidos explícitamente.
- Usa cookies con HttpOnly, Secure y SameSite.
- Activa CSRF en formularios y operaciones sensibles basadas en cookies.
- Configura cabeceras de seguridad como HSTS y X-Content-Type-Options.
9. Maneja errores sin filtrar información sensible
Una API no debe devolver trazas completas, rutas internas, variables de entorno, consultas SQL ni detalles de infraestructura al usuario final. Los errores deben ser útiles para el cliente, pero los detalles técnicos deben quedar en logs internos protegidos.
| Mala práctica | Buena práctica |
|---|---|
| Mostrar stack trace al usuario. | Responder con mensaje genérico y registrar el detalle en logs. |
| Devolver errores SQL completos. | Usar códigos controlados y mensajes seguros. |
| Guardar tokens en logs. | Enmascarar secretos y datos personales. |
10. Aplica límites de recursos y protección contra abuso
Una API puede ser vulnerable no solo por exposición de datos, sino por consumo excesivo de recursos. OWASP API Security Top 10 2023 incluye Unrestricted Resource Consumption como riesgo relevante para APIs.
En Python, esto implica limitar tamaño de archivos, cantidad de registros por consulta, profundidad de filtros, número de peticiones, tiempo de ejecución, tamaño de payload y operaciones costosas. Flask también documenta límites relacionados con el tamaño de formularios y recursos del proceso.
11. Checklist de buenas prácticas para Python seguro
- Usar entorno virtual por proyecto.
- Fijar versiones de dependencias.
- Auditar paquetes con pip-audit.
- Analizar código con Bandit.
- Validar entradas en servidor.
- Usar consultas SQL parametrizadas.
- No construir consultas concatenando texto.
- No guardar secretos en el repositorio.
- Generar tokens con secrets.
- No usar pickle con datos no confiables.
- Evitar shell=True salvo casos muy justificados.
- Aplicar autenticación fuerte en APIs.
- Validar autorización por objeto y acción.
- Configurar CORS de forma restrictiva.
- Usar HTTPS en producción.
- Proteger cookies con HttpOnly, Secure y SameSite.
- No exponer trazas de error al usuario.
- Enmascarar secretos en logs.
- Limitar tamaño de payloads y archivos.
- Aplicar rate limiting en endpoints sensibles.
- Separar configuración de desarrollo y producción.
- Desactivar debug en producción.
- Probar permisos con usuarios de distinto rol.
- Automatizar pruebas de seguridad en CI/CD.
- Documentar endpoints, permisos y riesgos.
12. Errores comunes al programar Python para APIs
- Dejar debug=True en producción.
- Subir archivos .env o claves API al repositorio.
- Confiar solo en validación del frontend.
- No verificar que el recurso pertenece al usuario autenticado.
- Usar dependencias sin revisar mantenimiento o vulnerabilidades.
- Registrar contraseñas, tokens o datos personales en logs.
- Permitir CORS abierto sin necesidad.
- Aceptar archivos sin validar tamaño, tipo y nombre.
- Usar pickle para datos recibidos de usuarios.
- No tener pruebas automatizadas para permisos y roles.
Preguntas clave
¿Python es seguro para crear APIs?
Sí. Python puede ser muy seguro si se aplican buenas prácticas: validación, autorización, dependencias auditadas, consultas parametrizadas, manejo seguro de secretos y configuración correcta del framework.
¿Qué framework es más seguro: Django, Flask o FastAPI?
Depende del uso. Django incluye muchas protecciones integradas; Flask ofrece flexibilidad, pero exige configurar más piezas; FastAPI facilita validación de datos y APIs modernas. La seguridad final depende de cómo se implementa la aplicación.
¿Qué herramientas mínimas debería usar?
Para empezar: entorno virtual, pip-audit para dependencias, Bandit para revisión estática, pruebas automatizadas y revisión manual de autenticación y autorización.
¿Por qué no debo usar pickle con archivos externos?
Porque la documentación oficial advierte que no se debe deserializar información de fuentes no confiables o manipulables. Para APIs y datos externos, es mejor usar formatos validados como JSON.
¿Qué vulnerabilidad es más frecuente en APIs?
OWASP API Security Top 10 2023 destaca problemas de autorización por objeto, autenticación rota, autorización por propiedades y consumo no restringido de recursos como riesgos principales en APIs.
Recomendamos
- Ciberseguridad en Linux: 50 herramientas gratuitas para proteger servidores y estaciones
- Cómo instalar Wazuh paso a paso como SIEM y XDR en Linux
- Guía completa de redes en Linux: comandos, diagnóstico, configuración y solución de problemas
- Comandos básicos que debes aprender para administrar tu servidor Linux
- Por qué los servidores usan Linux: ventajas para empresas y administradores TI
En resumen
Programar Python seguro desde cero significa adoptar una mentalidad preventiva. No se trata de agregar seguridad al final, sino de diseñar cada endpoint, consulta, archivo, dependencia y token con controles claros.
Las prácticas más importantes son simples pero poderosas: validar entradas, usar consultas parametrizadas, auditar dependencias, proteger secretos, evitar pickle con datos no confiables, controlar permisos por objeto, limitar recursos, registrar eventos útiles y automatizar revisiones de seguridad.
Conclusión editorial
Python es una gran herramienta para crear aplicaciones y APIs modernas, pero su seguridad depende del criterio del desarrollador. Un buen programador Python no solo escribe funciones: protege datos, limita permisos, revisa dependencias y diseña sistemas que fallan de forma controlada. La seguridad no debe ser un parche final; debe ser parte del código desde el primer commit.

