Building secure Rust: auditoria de dependências com cargo-audit
1. Introdução à segurança de dependências no ecossistema Rust
O ecossistema Rust é conhecido por suas garantias de segurança de memória, mas isso não elimina vulnerabilidades em dependências de terceiros. Um estudo do GitHub mostrou que mais de 90% das vulnerabilidades em projetos modernos vêm de dependências indiretas. No Rust, com mais de 150.000 crates no crates.io, o risco é real.
O cargo-audit é a ferramenta oficial do RustSec Working Group para auditoria de dependências. Ela consulta o RustSec Advisory Database — um repositório curado de vulnerabilidades (CVEs), crates retirados (yanked) e código inseguro (unsound) — e compara com as dependências do seu projeto.
// Exemplo conceitual: como o cargo-audit analisa seu Cargo.lock
// (pseudocódigo ilustrativo)
fn main() {
let dependencias = parse_cargo_lock();
let vulnerabilidades = rustsec_db::consultar(&dependencias);
for vuln in vulnerabilidades {
println!("⚠️ {}: {} ({})", vuln.crate_name, vuln.severity, vuln.cve_id);
}
}
2. Instalação e configuração inicial do cargo-audit
A instalação é simples:
cargo install cargo-audit
Para manter a versão atualizada, recomenda-se usar cargo install --force cargo-audit periodicamente ou adicionar ao seu gerenciador de pacotes do sistema.
Configuração básica:
Crie .cargo/audit.toml no diretório do projeto:
[advisories]
ignore = [] # Lista de advisories para ignorar (ex: "RUSTSEC-2023-0001")
severity_threshold = "low" # Ignora abaixo de "low"
E .cargo/advisories.toml para configurações avançadas:
[advisory_ids]
ignore = ["RUSTSEC-2020-0071"] # Ignora advisory específico
[severity]
deny = ["critical", "high"] # Falha em build para critical/high
Primeira execução:
cargo audit
A saída típica mostra:
Fetching advisory database from https://github.com/RustSec/advisory-db.git
Scanning Cargo.lock for vulnerabilities (30 dependencies)
============ Found 2 vulnerabilities ============
ID: RUSTSEC-2023-0001
Crate: example-crate 1.2.3
Severity: HIGH (7.5)
Title: Buffer overflow in example-crate
...
3. Compreendendo os tipos de vulnerabilidades reportadas
O RustSec Advisory Database classifica advisories em quatro categorias:
| Categoria | Descrição | Exemplo |
|---|---|---|
| Security | Vulnerabilidade de segurança confirmada | CVE-2023-XXXXX |
| Yanked | Crate retirado do crates.io (geralmente por bug crítico) | cargo yank |
| Unsound | Código unsafe que viola garantias de segurança |
Uso incorreto de std::mem::transmute |
| Notice | Aviso geral (ex: fim de suporte de versão) | Depreciação de API |
Severidade CVSS:
// Simulação de categorização de severidade
enum Severity {
Critical(f64), // >= 9.0
High(f64), // 7.0 - 8.9
Medium(f64), // 4.0 - 6.9
Low(f64), // 0.1 - 3.9
None, // 0.0
}
Exemplo prático de saída real:
ID: RUSTSEC-2023-0062
Package: openssl-src 111.25.3+1.1.1t
Type: unsound
Title: openssl-src contains multiple unsoundness issues in C code
Severity: HIGH (7.5)
Versões afetadas: >= 111.25.0, < 111.25.4
Patched: >= 111.25.4
4. Estratégias de mitigação e remediação
Atualização segura:
# Atualiza dependências de forma segura
cargo update -p crate-vulneravel
# Verifica se a vulnerabilidade foi corrigida
cargo audit
Correção automática (experimental):
cargo audit fix
Esta ferramenta tenta atualizar automaticamente as dependências vulneráveis para versões corrigidas.
Isolamento com cargo-deny:
cargo install cargo-deny
cargo deny init
Configure deny.toml:
[advisories]
vulnerability = "deny"
unsound = "deny"
yanked = "deny"
notice = "warn"
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-3-Clause"]
Verificação com cargo-vet (Mozilla):
cargo install cargo-vet
cargo vet init
cargo vet
cargo-vet verifica se cada dependência foi auditada por uma entidade confiável (Mozilla, Google, etc.) ou se você precisa auditar manualmente.
5. Integração contínua e automação de auditoria
GitHub Actions:
# .github/workflows/audit.yml
name: Security audit
on:
push:
branches: [main]
schedule:
- cron: '0 0 * * 0' # Semanal
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/audit-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
GitLab CI:
# .gitlab-ci.yml
security-audit:
stage: test
script:
- cargo install cargo-audit
- cargo audit --deny warnings
only:
- main
- tags
Configuração para falhar em build:
# Falha se encontrar qualquer vulnerabilidade
cargo audit --deny warnings
# Falha apenas para critical/high
cargo audit --deny warnings --severity-threshold high
6. Boas práticas avançadas de auditoria
Saída JSON para processamento programático:
cargo audit --json > audit-report.json
Processe com Python ou Rust:
use serde_json::Value;
use std::fs;
fn main() {
let data: Value = serde_json::from_str(
&fs::read_to_string("audit-report.json").unwrap()
).unwrap();
if let Some(vulnerabilities) = data["vulnerabilities"]["found"].as_array() {
for vuln in vulnerabilities {
println!("CVE: {}", vuln["advisory"]["id"]);
}
}
}
Políticas personalizadas com cargo-deny:
[advisories]
ignore = ["RUSTSEC-2023-0001"] # Falso positivo conhecido
[licenses]
deny = ["GPL-3.0"] # Empresa não permite GPL
[sources]
allow-git = ["https://github.com/meu-projeto/*"]
Auditoria de dependências transitivas:
# Visualiza árvore de dependências
cargo tree --invert -p crate-vulneravel
# Verifica apenas dependências diretas
cargo audit --direct
7. Casos reais e lições aprendidas
Caso 1: Cargo RCE (2022)
Uma vulnerabilidade no próprio cargo permitia execução remota de código ao baixar crates maliciosos. O advisory RUSTSEC-2022-0014 foi emitido e corrigido em versões posteriores.
Caso 2: libp2p DoS (2023)
A biblioteca de rede P2P libp2p teve uma vulnerabilidade de negação de serviço (RUSTSEC-2023-0036) que afetava todas as versões até 0.52.0.
Caso 3: OpenSSL bindings
Diversos advisories para openssl-src (vulnerabilidades herdadas do C) são comuns. A lição: sempre audite bindings de bibliotecas C.
Erros comuns:
- Ignorar advisories sem investigação adequada
- Não atualizar a base de advisories (
cargo auditfaz automaticamente) - Confundir
unsoundcomsecurity(unsound pode ser usado internamente sem risco) - Não auditar dependências de desenvolvimento (
[dev-dependencies])
8. Conclusão e próximos passos
Checklist de segurança para Rust em produção:
- [ ]
cargo auditintegrado no CI/CD - [ ]
cargo denyconfigurado com políticas de licenças - [ ]
cargo vetpara auditoria de dependências críticas - [ ] Revisão periódica dos advisories ignorados
- [ ] Manutenção de versões atualizadas (
cargo updatesemanal)
Ferramentas complementares:
| Ferramenta | Propósito |
|---|---|
cargo-crev |
Sistema de revisão por pares de dependências |
cargo-geiger |
Detecta uso de unsafe em dependências |
cargo-spellcheck |
Verifica erros de digitação em nomes de crates (typosquatting) |
Recursos para aprofundamento:
- RustSec Working Group (WG) — mantenedores do cargo-audit
- RustSec Advisory Database — repositório oficial de advisories
- OWASP Top 10 for Rust — guia de segurança específico para Rust
Referências
- Documentação oficial do cargo-audit — Guia completo de instalação, configuração e uso da ferramenta
- RustSec Advisory Database (GitHub) — Repositório oficial de advisories de segurança para o ecossistema Rust
- cargo-deny Documentation — Ferramenta complementar para políticas de licenças e bloqueio de dependências
- cargo-vet by Mozilla — Sistema de auditoria de dependências baseado em revisão por pares
- RustSec Working Group — Página oficial do grupo de trabalho de segurança do Rust, com blog e comunicados
- OWASP Top 10 for Rust — Guia de vulnerabilidades comuns em aplicações Rust
- Common Vulnerabilities and Exposures (CVE) Database — Base de dados oficial de vulnerabilidades conhecidas
- Rust Blog: Security and the Rust ecosystem — Artigo oficial sobre segurança no ecossistema Rust