PyPI bloquea archivos nuevos en versiones de más de 14 días
PyPI ya rechaza subir archivos nuevos a versiones publicadas hace más de 14 días, una medida preventiva contra el envenenamiento de releases estables si se filtran tokens de publicación.
El Python Package Index (PyPI) ha cerrado una puerta que llevaba años abierta sin que nadie la hubiera cruzado. Desde el pasado 22 de julio, el repositorio rechaza la subida de archivos nuevos a cualquier release que tenga más de 14 días de antigüedad. Lo cuenta Seth Larson, responsable de seguridad en la Python Software Foundation, en una nota que recoge Simon Willison en su weblog.
El detalle que hace interesante el cambio es el motivo. Según Larson, la restricción existe para evitar que releases antiguas y estables puedan ser envenenadas si los tokens de publicación o los workflows de un proyecto se ven comprometidos. Y admite algo poco habitual en un anuncio de seguridad: que ellos sepan, este vector no se ha llegado a explotar. No había razón técnica que impidiera hacerlo, más allá de que los atacantes no sabían que era posible.
Qué se podía hacer antes
Hasta ahora, nada impedía añadir un archivo nuevo (por ejemplo, una wheel para una plataforma que antes no estaba cubierta) a una versión publicada años atrás. En condiciones normales es una comodidad. En manos de un atacante con acceso a las credenciales de publicación de un proyecto, es una vía perfecta para colar código malicioso donde nadie lo espera: dentro de una versión vieja, marcada como estable, que miles de despliegues reproducibles fijan en sus ficheros de dependencias.
El peligro está justo en esa confianza. Una release de hace tres años que no ha cambiado nunca no levanta sospechas. Si de repente aparece un artefacto nuevo dentro de ella, la mayoría de pipelines automáticos lo aceptarían sin rechistar. Cerrar esa ventana a los 14 días reduce la superficie de ataque sin molestar al flujo legítimo, porque publicar los binarios de una versión rara vez lleva más de dos semanas.
Un patrón de endurecimiento
El cambio, detallado en el pull request 19727 de warehouse, encaja en una tendencia más amplia de PyPI y del resto de repositorios de paquetes: ir cerrando comportamientos legítimos pero peligrosos que sobreviven por inercia. En los últimos años hemos visto llegar la autenticación en dos factores obligatoria para mantenedores, los Trusted Publishers basados en OpenID Connect para evitar tokens de larga vida, y ahora esta ventana temporal para congelar releases estables.
La lógica es siempre la misma: la mayoría de los ataques a la cadena de suministro no explotan un fallo exótico, sino una función normal usada de forma maliciosa. Reducir lo que se puede hacer con credenciales comprometidas suele valer más que perseguir vulnerabilidades concretas. Es prevención por diseño, no reacción a un incidente ya ocurrido.
Para quién importa
Si mantienes un paquete en PyPI, el impacto práctico es mínimo: solo notarás el cambio si intentas añadir archivos a una versión con más de dos semanas, algo raro en un flujo sano. La recomendación implícita es publicar todos los artefactos de una release en su ventana inicial y, si necesitas un binario nuevo más tarde, sacar una versión nueva en lugar de retocar una vieja.
Si tu trabajo consiste en asegurar cadenas de dependencias, la lectura es más de fondo. Merece la pena revisar dónde se pinean las versiones, si los pipelines verifican hashes y qué pasaría si un token de publicación se filtrase hoy. El movimiento de PyPI reduce un riesgo concreto, pero no sustituye a fijar dependencias por hash ni a auditar quién tiene permisos de publicación.
En ElephantPink solemos insistir en que la seguridad de la cadena de suministro se gana con decisiones aburridas como esta, no con herramientas vistosas. Cerrar un vector que nunca se explotó, antes de que alguien lo descubra, es exactamente el tipo de mantenimiento poco glamuroso que sostiene un ecosistema del que dependen millones de proyectos. Ojalá cundiera el ejemplo en otros repositorios.
Fuentes
Seguir leyendo
sqlite-utils 4.1 permite insertar filas con código Python
La versión 4.1 de sqlite-utils suma una opción --code que permite generar las filas a insertar con un bloque de código Python, sin pasar antes por un fichero intermedio.
sqlite-utils 4.0rc3: claves foráneas compuestas antes de la versión estable
Simon Willison publica sqlite-utils 4.0rc3 con claves foráneas compuestas y columnas insensibles a mayúsculas, dos cambios que retrasan la esperada versión 4.0 estable.
sqlite-utils 4.0rc2: Claude Fable escribe casi toda la release por 149 dólares
El creador de Datasette encarga a Claude Fable la revisión final de sqlite-utils 4.0: el modelo detectó cinco release blockers y escribió casi toda la rc2 por unos 149 dólares.