Hace quince años, si alguien decía "software inseguro", la mente iba a PHP. No porque el lenguaje fuera malo en sí, sino porque era el que todo el mundo usaba: la web se construía sobre PHP, y el lenguaje más usado es siempre el más atacado. Hoy esa corona cambió de cabeza. El lenguaje por defecto del mundo —y, sobre todo, de la inteligencia artificial— es Python. Y con la corona viene la diana.
Conviene mirar qué pasó de verdad con PHP, porque la lección no es la que parece.
La lección de PHP no era "el lenguaje es malo"
PHP se ganó su fama por tres cosas, y ninguna era la sintaxis:
- Conveniencias peligrosas por defecto.
register_globals,includede URLs remotas,evala mano. Cosas que hacían la vida fácil al programador y abrían la puerta de par en par al atacante. - Ubicuidad. Estaba en cada hosting compartido del planeta. Una sola clase de fallo se multiplicaba por millones de sitios.
- Una generación de desarrolladores sin formación en seguridad, copiando y pegando el mismo patrón vulnerable.
PHP moderno (7 y 8) es un lenguaje razonable y mucho más seguro. Pero el daño reputacional ya estaba hecho, y la lección quedó: cuando un lenguaje se vuelve la base de todo, sus decisiones "cómodas" se convierten en vulnerabilidades a escala planetaria.
Hoy la corona es de Python
Python es el lenguaje más popular del mundo por casi cualquier medida. Y, lo que importa aquí: es la base de la inteligencia artificial. PyTorch, TensorFlow, Hugging Face, todas las librerías de LLMs, todo el data science, la mayoría de los agentes de IA que se están desplegando ahora mismo: Python. Si la IA es la ola, Python es el agua.
Eso lo convierte en el blanco grande de esta década, exactamente como PHP lo fue de la suya. Pero el peligro cambió de sitio. Ya no está tanto en el lenguaje: está en lo que arrastra detrás.
El peligro real número uno: la cadena de suministro
Una aplicación de Python moderna casi nunca es "tu código". Es tu código más cientos de dependencias que bajas de PyPI, muchas de las cuales ni sabes que están ahí (dependencias de dependencias). Cada una es código que corre con tus permisos. Los ataques de 2024–2026 a los registros de paquetes no han sido accidentes aislados: han sido sistemáticos.
Las vías son conocidas y siguen funcionando:
- Typosquatting. Un paquete llamado
python-requestsen vez derequests. Te equivocas de una letra y acabas de instalar malware. - Confusión de dependencias. Si tu empresa tiene un paquete interno llamado
utils, alguien sube unutilspúblico con un número de versión más alto, y tu instalador se baja el del atacante. - Código que se ejecuta al instalar. Un
pip installde un paquete en formato sdist ejecuta susetup.pyen tu máquina, con tu usuario, antes de que escribas una sola línea. Es la misma clase de agujero que hizo famoso elpostinstallde npm. - Cuentas de mantenedor comprometidas. El paquete es legítimo; el dueño perdió su contraseña. La siguiente versión trae un regalo.
Esto no es teoría. En diciembre de 2022, la rama nightly de PyTorch —una de las piezas centrales del mundo de la IA— sufrió un ataque de confusión de dependencias: un paquete malicioso llamado torchtriton subido a PyPI tomó precedencia sobre el legítimo y exfiltraba información del sistema de quien lo instalara. El proyecto más visible del ecosistema de IA, comprometido por la vía más mundana: el instalador de paquetes.
El vector específico de la IA: cargar un modelo es ejecutar código
Aquí está la parte que casi nadie fuera de la seguridad conoce, y es la que de verdad conecta "IA" con "peligro".
Durante años, la forma estándar de guardar y compartir un modelo entrenado en Python ha sido pickle, el formato de serialización nativo del lenguaje. El problema: deserializar un pickle puede ejecutar código arbitrario. No es un bug; es cómo funciona pickle por diseño.
Y los modelos de IA se distribuyen así. La gente baja pesos de modelos de repositorios públicos, de desconocidos, y los carga con torch.load(...). Cargar ese archivo —en las configuraciones antiguas, que todavía abundan— es correr el código que el autor del archivo haya querido meter dentro. Descargar un modelo "para probarlo" era, literalmente, ejecutar un programa de alguien a quien no conoces.
La comunidad reaccionó. El formato safetensors de Hugging Face nació precisamente para esto: guarda solo números, nunca código. Y las versiones recientes de PyTorch cambiaron su valor por defecto para no deserializar código a menos que se lo pidas explícitamente. Pero hay millones de archivos pickle circulando, y una enorme cantidad de tutoriales, notebooks y proyectos que siguen haciendo lo de siempre.
Esa es la frase precisa, no "Python es inseguro": en el mundo de la IA, el patrón normal de "descarga este modelo y pruébalo" es un patrón de ejecución de código no confiable.
Qué hacer (lo que sí mueve la aguja)
No se trata de abandonar Python —eso no va a pasar—. Se trata de tratar sus dependencias y sus modelos como lo que son: código no confiable que corre con tus permisos.
- Fija y verifica tus dependencias.
pip install --require-hashescon un lockfile. Si el hash no cuadra, no se instala. Nada de rangos de versión abiertos en producción. - Corta la ejecución al instalar. Prefiere wheels a sdists; audita cualquier paquete que insista en ejecutar código en la instalación.
- Nunca cargues un
picklede origen desconocido. Exigesafetensors. Si tienes que usartorch.load, hazlo con la opción que impide deserializar código. - Aísla. Lo que baja de internet y lo que lo procesa no deberían correr con acceso a tus secretos ni a tu red. Un contenedor o un espacio de nombres sin red cuesta poco y tapa mucho.
- Haz inventario (SBOM). Si no sabes qué paquetes y qué modelos tienes, no puedes saber si alguno de ellos ya te comprometió.
La raíz del asunto
El peligro de Python no es un defecto de Python. Es la consecuencia de ser la base de todo en un momento en que atacar la cadena de suministro es la táctica de moda. Es la misma historia de PHP, un ecosistema más tarde y con mucho más en juego: ahora lo que se construye sobre esa base no son blogs, son los sistemas de IA que empiezan a tomar decisiones.
En Xiliux construimos nuestras herramientas de seguridad en Rust, como un único binario, sin un árbol de dependencias que alguien pueda envenenar y sin formatos que ejecuten código al abrirse. No por moda: porque la superficie de ataque que no existe no hay que defenderla. Si te preocupa qué estás ejecutando de verdad cuando instalas o cuando cargas un modelo, hablemos.
Xiliux