La crate maliciosa de Rust Arrayref ejecuta una carga útil en tiempo de compilación

Una crate de Rust comprometida recientemente, `arrayref`, usó un script malicioso en tiempo de compilación para ejecutar una carga útil en máquinas de desarrolladores, reavivando los temores sobre los ataques a la cadena de suministro de software más allá del mundo de JavaScript/npm. Los comentaristas debaten cuánto de la culpa recae en la capacidad de Cargo para ejecutar por defecto código arbitrario de `build.rs` y proc-macro, y proponen mitigaciones como aislar las compilaciones, imponer edades mínimas de publicación, mejores herramientas de auditoría y bibliotecas curadas o “bendecidas”. El incidente también alimenta un debate más amplio sobre la cultura de dependencias y el diseño de la biblioteca estándar, y algunos abogan por ecosistemas “con todo incluido” para reducir la dependencia de árboles de dependencias extensos y difíciles de verificar.

Qué hizo el ataque y por qué preocupa

  • Una pequeña crate popular fue comprometida a través de la cuenta de su mantenedor; una nueva versión añadió un script de compilación malicioso y una dependencia de proc-macro.
  • En Windows, el script de compilación descargó una carga útil remota, la escribió en un script temporal de PowerShell y la ejecutó mediante un lanzador de VBScript para escapar del job object de Cargo.
  • Varios comentaristas señalan que esto apunta más a máquinas de desarrolladores/CI, con secretos y credenciales en la nube, que a entornos de ejecución de usuario final.

Amenazas en tiempo de compilación frente a tiempo de ejecución

  • Muchos sostienen que los scripts de compilación y los proc macros son especialmente peligrosos porque se ejecutan automáticamente durante la compilación, a menudo antes de la revisión del código.
  • Otros contraargumentan que los atacantes pueden mover la carga útil al código normal de la biblioteca y activarla en pruebas o en tiempo de ejecución, así que centrarse solo en build.rs es incompleto.
  • Aun así, algunos mantienen que el tiempo de compilación tiene un acceso más amplio a secretos que el tiempo de ejecución y merece un endurecimiento especial.

Cargo, crates.io y respuesta al incidente

  • La versión maliciosa fue eliminada (no solo retirada) de crates.io en unas ~1,5 horas; algunos elogian la velocidad.
  • Otros critican la UX: las versiones eliminadas desaparecen de la lista de versiones, al principio no había ningún aviso visible, y se les dice a los usuarios que ejecuten comandos find improvisados en lugar de una ruta de auditoría integrada de cargo.
  • Hay debate sobre si crates.io estaba “despreparado” o si hizo lo mejor posible bajo restricciones de voluntariado.

Mitigaciones y herramientas propuestas

  • Hay un fuerte apoyo para:
    • Una edad mínima de publicación/actualización (min-publish-age) para evitar lanzamientos maliciosos recién publicados.
    • Mejores valores predeterminados: bloquear o allowlist explícitamente build.rs/proc-macros, y marcar con mucha visibilidad cuando una dependencia los añade por primera vez.
    • Aislar scripts de compilación (y a veces pruebas) con sistema de archivos restringido y sin red, aunque algunos dicen que el aislamiento multiplataforma es difícil y se puede eludir fácilmente.
  • Herramientas existentes mencionadas: cargo-deny, cargo-vet, cargo-crev, min-publish-age (nightly), compilaciones sin conexión, vendoring, aislamientos externos (bwrap, Landlock, etc.).

Tamaño de la stdlib, cultura de dependencias y comparación del ecosistema

  • Gran debate sobre las muchas crates pequeñas de Rust frente a stdlibs “con todo incluido” (Go, .NET, Java, APIs de Apple, Python).
  • Algunos argumentan que las stdlibs grandes y las crates “bendecidas” y curadas reducen la proliferación de dependencias y la superficie de ataque; otros enfatizan que las stdlibs grandes se estancan y aun así tienen vulnerabilidades.
  • Comparaciones con npm/Node, Python, C++, Go: el consenso es que cualquier ecosistema con gestión fácil de dependencias y muchos micro-paquetes enfrenta un riesgo similar de cadena de suministro; la cultura y la curación importan tanto como el diseño del lenguaje.

Lecciones más amplias

  • Muchos abogan por entornos de desarrollo en contenedores o aislados y por tratar por defecto como no confiables las crates nuevas o de nicho.
  • Hay una discusión aspiracional sobre lenguajes y sistemas operativos basados en capacidades o efectos, pero otros lo ven principalmente como un problema social y de financiación más que puramente técnico.