Nástroje pro statickou analýzu kódu pro vývojáře v Rustu

Sada nástrojů pro vývojáře v Rustu: Nejlepší nástroje pro statickou analýzu kódu

Kompilátor Rustu je nejnázorovějším recenzentem kódu, se kterým většina vývojářů kdy bude pracovat. Jeho systém vlastnictví, kontrola výpůjček a doživotní vynucování eliminují celé kategorie chyb, které sužují kódové základny C a C++. Kompilátor, který zabraňuje chybám paměti, však není totéž co komplexní systém kvality. Logické chyby, nezabezpečené řetězce závislostí, nebezpečné zneužití bloků, anti-vzory pro výkon a stylový drift - to vše přežije. rustcTýmy, které dodávají spolehlivý Rust ve velkém měřítku, kombinují kompilátor s vrstvenou sadou nástrojů pro statickou analýzu, z nichž každý pokrývá jinou část povrchu kvality.

Výběr špatné kombinace způsobuje plýtvání časem v oblasti CI a generuje šum, který se vývojáři naučí ignorovat. Výběr správné kombinace způsobí, že se přísnost kompilátoru jeví jako podlaha, nikoli strop. Nástroje v této příručce jsou uspořádány podle toho, co skutečně dělají, nikoli abecedně, takže týmy mohou vytvořit sadu nástrojů, která pokrývá všechny tři vrstvy kvality: linting a idiomy, zabezpečení závislostí a hloubkové ověřování kódu kritického z hlediska bezpečnosti nebo citlivého na bezpečnost.

SMART TS XL

Udržování kvality v moderním vývoji v Rustu je náročné, a to i přes silné záruky bezpečnosti, které jazyk poskytuje. SMART TS XL je navržen tak, aby pomohl týmům vytvářet spolehlivý, udržovatelný a bezpečný software tím, že nabízí hloubkové statické analýzy přizpůsobené jedinečným vlastnostem Rustu. Podporuje profesionální inženýrské pracovní postupy tím, že včas odhaluje problémy, vynucuje konzistenci a snižuje úsilí potřebné k ruční kontrole.

Tři vrstvy statické analýzy rzi

Pochopení toho, který nástroj kam patří, zabraňuje časté chybě, kdy se používá formální verifikátor tam, kde by stačil linter, nebo se spoléhá na linter tam, kde je vyžadován bezpečnostní skener. Každý zralý projekt v Rustu by měl pokrývat všechny tři vrstvy.

Vrstva 1: Župancování a styling Zachycuje idiomatická porušení, běžné chyby a problémy s údržbou. Nástroje: Clippy, rustfmt, rust-analyzer.

Vrstva 2: Závislost a zabezpečení dodavatelského řetězce Audituje bedny třetích stran, zda neobsahují známé zranitelnosti a porušení zásad. Nástroje: cargo-audit, cargo-deny, cargo-auditable.

Vrstva 3: Hloubkové ověření Nachází problémy s bezpečností paměti v nebezpečném kódu, nedefinovaném chování a formálně dokazuje vlastnosti kritických funkcí. Nástroje: Miri, Kani, MIRAI, Rudra, Creusot, Prusti.

Níže uvedená tabulka porovnává jednotlivé hlavní nástroje s jejich vrstvami, náklady, vhodností pro CI a primárním případem použití:

NástrojvrstvaStátVhodné pro CIPrimární případ použití
ClippyPodšívkaZdarma / OSSAnoIdiomatické linting, styl, běžné chyby
rustfmtPodšívkaZdarma / OSSAnoVynucení formátování kódu
analyzátor rziLinting / DXZdarma / OSSČástečnýDiagnostika IDE, inline analýza
audit nákladuZabezpečení závislostíZdarma / OSSAnoZnámé CVE v bednách
odmítnutí nákladuZabezpečení závislostíZdarma / OSSAnoLicence, duplikáty, doporučení
auditovatelný nákladZabezpečení závislostíZdarma / OSSAnoVložení dat závislostí do binárních souborů
MiriHloubkové ověřeníZdarma / OSSSelektivníNedefinované chování v nebezpečném kódu
KaniHloubkové ověřeníZdarma / OSSSelektivníFormální ověření, kontrola modelu
MIRAIHloubkové ověřeníZdarma / OSSSelektivníAbstraktní interpretace, analýza kontaminace
RudraHloubkové ověřeníZdarma / OSSČlánky vyžadující průzkumChyby v zabezpečení paměti v nebezpečném Rustu
SemgrepPrůřezovéBezplatná úroveň + placenáAnoVlastní bezpečnostní vzory, vícejazyčné
SonarCloudPrůřezovéBezplatná úroveň + placenáAnoPrůběžná brána kvality, dashboardy

Vrstva 1: Linting, styl a zkušenosti vývojářů

Clippy

Clippy je definitivním výchozím bodem pro statickou analýzu v Rustu. Dodává se s oficiální sadou nástrojů Rust a nabízí více než 700 lintů pokrývajících správnost, výkon, styl, složitost a omezení. Je to nástroj, který většina týmů Rust používá denně, a to z dobrého důvodu: zachycuje skutečné chyby, nejen názory na styl.

praštit

# Run all lints including pedantic and nursery groups
cargo clippy -- -W clippy::all -W clippy::pedantic

# Fail CI on any warning
cargo clippy -- -D warnings

# Check specific lint group
cargo clippy -- -W clippy::correctness -W clippy::suspicious

Kategorie lintů v Clippyho nástroji stojí za to explicitně pochopit:

KategorieCo to chytí
correctnessKód, který je téměř jistě chybný (vždy odmítnout)
suspiciousKód, který je pravděpodobně chybný nebo velmi překvapivý
styleNeidiomatické vzorce s jasným zlepšením
complexityZbytečně složité konstrukce
performanceKód, který se kompiluje, ale běží pomaleji, než by měl
pedanticPřísná pravidla, názorová (povolit selektivně)
restrictionPravidla, která byste mohli chtít vynutit v konkrétních kontextech
nurseryNové vlákna mohou vést k falešně pozitivním výsledkům

kontrola nákladu vs. Clippy: cargo check Ověřuje správnost typu a kompilaci bez generování binárního souboru. Je rychlý a vhodný pro ověření sestavení. cargo clippy běží cargo check plus veškerá analýza vláken. Pro CI spusťte cargo check pro rychlou zpětnou vazbu při kompilaci a cargo clippy -- -D warnings jako samostatná kvalitní brána. Nejsou zaměnitelné: cargo check nezachytí idiomatické problémy a cargo clippy je pomalejší.

Konfigurace Clippyho přes clippy.toml nebo inline atributy dávají týmům kontrolu nad šumem:

toml

# clippy.toml
avoid-breaking-exported-api = false
msrv = "1.70"

rez

// Suppress a lint for one function with documented reason
#[allow(clippy::too_many_arguments)]
fn complex_setup(...) { ... }

Co Clippy nepokrývá: hloubkovou analýzu datových toků napříč moduly, skenování bezpečnostních zranitelností v závislostech, formální důkaz správnosti ani vlastní pravidla specifická pro danou organizaci. Tyto nástroje vyžadují nástroje v ostatních vrstvách.

rustfmt

rustfmt vynucuje konzistentní formátování v celé kódové základně pomocí cargo fmt, rustfmt.toml konfigurační soubor nastavuje stylistická pravidla pro celý projekt. V CI, cargo fmt -- --check Pokud by byl jakýkoli soubor přeformátován, ukončí se s nenulovým kódem, což z něj dělá čistou bránu s nulovými konfiguračními režijními náklady:

praštit

# Check formatting without modifying files (CI mode)
cargo fmt -- --check

# Apply formatting (developer mode)
cargo fmt

Integrace s analyzátorem rust a IDE

rust-analyzer je implementace protokolu Language Server Protocol pro Rust, která poskytuje diagnostiku v reálném čase, dokončování, přechod na definici a inline varování Clippy v jakémkoli editoru kompatibilním s LSP. Nahradil zastaralý RLS (Rust Language Server) a měl by být jediným jazykovým serverem používaným v nových projektech.

Z pohledu statické analýzy rust-analyzer zobrazuje Clippy linty přímo v textu, jak vývojáři píší, a poskytuje tak okamžitou zpětnou vazbu k problémům se stylem a správností v okamžiku jejich uvedení, aniž by vyžadoval samostatné spuštění terminálu:

json

// VS Code settings.json: enable Clippy via rust-analyzer
{
  "rust-analyzer.check.command": "clippy",
  "rust-analyzer.check.extraArgs": [
    "--", "-W", "clippy::all", "-W", "clippy::pedantic"
  ]
}

Rust-analyzer také poskytuje vložené nápovědy pro odvozené typy, doby trvání vypůjčených parametrů a názvy parametrů, což je užitečné pro kontrolu neznámého kódu bez nutnosti navigace k definicím.

Vrstva 2: Závislost a bezpečnost dodavatelského řetězce

audit nákladu

audit nákladu kontroluje Cargo.lock soubor s databází RustSec Advisory Database a identifikuje známé CVE v přímých a tranzitivních závislostech. Jedná se o minimální nástroj pro zabezpečení závislostí, který by měl každý projekt Rust běžet v CI.

praštit

# Install
cargo install cargo-audit

# Run audit
cargo audit

# Ignore a specific advisory (document the reason in comments)
cargo audit --ignore RUSTSEC-2024-0001

# JSON output for pipeline integration
cargo audit --json | jq '.vulnerabilities'

Cargo-audit se zabývá pouze známými, publikovanými doporučeními. Nedokáže detekovat zranitelnosti ve vašem vlastním kódu, problémy, které ještě nejsou v databázi RustSec, ani porušení zásad, jako jsou například nežádoucí licence.

odmítnutí nákladu

cargo-deny rozšiřuje správu závislostí nad rámec známých CVE na dodržování předpisů v oblasti licencí, detekci duplicitních boxů a vlastní zásady pro zákaz/povolení. Jedná se o komplexnější nástroj pro organizace s požadavky na dodržování předpisů:

toml

# deny.toml
[advisories]
vulnerability = "deny"
unmaintained = "warn"

[licenses]
allow = ["MIT", "Apache-2.0", "ISC", "BSD-2-Clause", "BSD-3-Clause"]
deny = ["GPL-2.0"]
copyleft = "warn"

[bans]
multiple-versions = "warn"

praštit

cargo install cargo-deny
cargo deny check

auditovatelný náklad

cargo-auditable vkládá kompletní strom závislostí do kompilovaných binárních souborů Rust jako strukturovaná metadata ve vyhrazené sekci linkeru. To umožňuje auditovat nasazené binární soubory bez přístupu ke zdrojovému kódu, což je cenné pro kontrolu zabezpečení po nasazení a transparentnost dodavatelského řetězce:

praštit

cargo install cargo-auditable
cargo auditable build --release
# The binary now contains auditable dependency metadata
# Audit a binary directly:
cargo audit bin ./target/release/my-service

Vrstva 3: Hloubkové ověření

Nástroje v této vrstvě vyžadují více nastavení, více odborných znalostí a delší dobu analýzy. Nejsou vhodné pro každou funkci v každé kódové základně. Jsou nezbytné pro nebezpečný kód, kryptografické implementace, logiku parseru zpracovávající nedůvěryhodný vstup a jakýkoli kód, kde je třeba správnost spíše prokázat než testovat.

Miri: Detekce nedefinovaného chování

Miri je interpret pro Rustovu střední úroveň reprezentace (MIR), který spouští kód způsobem, který detekuje nedefinované chování, které kompilátor umožňuje, ale porušuje bezpečnostní záruky Rustu: přístup k paměti mimo hranice v nebezpečných blocích, použití po uvolnění bloku, dereference nesprávně zarovnaných ukazatelů, závody dat ve vícevláknovém nebezpečném kódu a porušení Rustova modelu aliasování.

praštit

# Install Miri (requires nightly)
rustup +nightly component add miri

# Run tests under Miri
cargo +nightly miri test

# Enable strict aliasing validation
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test

Co Miri detekujenedefinované chování v unsafe bloky, narušení přístupu k paměti, použití po uvolnění paměti, nesprávně zarovnané přístupy, přetečení celočíselných čísel v ladicích sestaveních, závody dat v nebezpečném souběžném kódu.

Co Miri nepokrývá: logické chyby v bezpečném kódu, které nezahrnují nedefinované chování, zranitelnosti závislostí, styl kódu nebo problémy s výkonem.

Integrace CIMiri běží 10–50krát pomaleji než cargo testSpouštět selektivně na modulech obsahujících unsafe kódu, nebo podle nočního rozvrhu, nikoli při každém commitu:

yaml

- name: Miri on unsafe modules
  run: |
    rustup +nightly component add miri
    cargo +nightly miri test --package my-unsafe-crate

Kani: Kontrola modelu a formální ověření

Kani, vyvinutý společností Amazon Web Services, je kontrolor modelů, který formálně ověřuje vlastnosti kódu Rust vyčerpávajícím prozkoumáváním cest provádění až do definované hranice. Tam, kde Miri spouští skutečné testovací případy a nachází konkrétní chyby, Kani dokazuje nebo vyvrací, že vlastnosti platí pro všechny vstupy v rámci jeho rozsahu analýzy.

Kani vyžaduje zápis ověřovacích postrojů: funkcí, které definují vstupní prostor a vlastnosti k ověření:

rez

#[cfg(kani)]
mod verification {
    use super::*;

    #[kani::proof]
    fn verify_add_no_overflow() {
        let a: u32 = kani::any();
        let b: u32 = kani::any();
        if a.checked_add(b).is_some() {
            let result = safe_add(a, b);
            assert!(result == a + b);
        }
    }
}

praštit

cargo install --locked kani-verifier
cargo kani setup
cargo kani

Nejvhodnější pro: bezpečnostně kritické funkce, implementace protokolů, aritmetiku ve finančním nebo kryptografickém kódu a jakoukoli funkci, kde je potřeba prokázat, nejen otestovat, vlastnost správnosti.

MIRAI: Abstraktní interpretace a analýza nákazy

MIRAI, vyvinutý společností Facebook Research, využívá abstraktní interpretaci k analýze MIR v Rustu. Provádí interprocedurální analýzu, která sleduje, jak hodnoty procházejí voláním funkcí, detekuje potenciální paniky, porušení smluv a šíření škodlivých kódů.

rez

use mirai_annotations::*;

fn divide(a: i32, b: i32) -> i32 {
    precondition!(b != 0);  // MIRAI verifies all callers satisfy this
    a / b
}

MIRAI vyžaduje noční kompilátor Rustu a má strmou křivku nastavení, díky čemuž je nejvhodnější pro týmy se specializovanou kapacitou bezpečnostního inženýrství nebo s požadavky na kvalitu zaměřenou na výzkum.

Rudra: Bezpečnost paměti v nebezpečném knihovním kódu

Rudra provádí analýzu celého programu napříč balíčky, aby detekovala chyby v zabezpečení paměti specifické pro model vlastnictví Rustu: porušení bezpečnosti vlastností Send/Sync, problémy s životností vyššího druhu, které umožňují nežádoucí prodloužení životnosti, a problémy s panikou v nebezpečném kódu. Původně byl vyvinut výzkumníky, funguje jako plugin kompilátoru a vyžaduje specifickou noční verzi. Spouštějte jej plánovaně pro balíčky knihoven s nebezpečnými interními prvky, nikoli při každém commitu.

Creusot a Prusti: Deduktivní ověření

Creusot a Prusti jsou deduktivní ověřovací nástroje, které dokazují matematické vlastnosti programů v Rustu. Oba vyžadují formální specifikace (předpodmínky, postpodmínky, invarianty smyček) a používají automatizované dokazovače vět k ověření implementací vůči těmto specifikacím. Zaměřují se na omezenou podmnožinu bezpečného Rustu a vyžadují znalost formálních metod. Vhodné pro regulovaná odvětví, vývoj kryptografických knihoven nebo jakýkoli kontext, kde je matematický důkaz správnosti smluvním nebo regulačním požadavkem.

Další nástroje, které stojí za to zahrnout

Semgrep pro vlastní bezpečnostní vzory

Semgrep poskytuje statickou analýzu založenou na vzorcích, která funguje současně ve více jazycích. V Rustu umožňuje týmům psát vlastní pravidla vynucující bezpečnostní zásady organizace a vzory specifické pro kódovou základnu, které Clippy nedokáže vyjádřit:

yaml

# Custom rule: flag .unwrap() in production paths
rules:
  - id: no-unwrap-in-production
    pattern: $X.unwrap()
    message: "Use proper error handling instead of .unwrap()"
    languages: [rust]
    severity: WARNING

Semgrep také poskytuje spravovaný registr pravidel s bezpečnostními pravidly Rust spravovanými komunitou.

SonarCloud / SonarQube pro nepřetržité brány kvality

SonarCloud poskytuje průběžnou analýzu kvality kódu s dashboardem, sledováním trendů a dekorací pull requestů. Podpora Rust pokrývá běžné vzorce chyb, bezpečnostní hotspoty a pachy kódu. Pro podnikové týmy, které již používají SonarCloud pro jiné jazyky, přidání Rustu do stejného pipeline poskytuje jednotný přehled o kvalitě v celém stacku.

Vytvoření vrstveného CI/CD pipeline

Následující pracovní postup akcí GitHubu představuje praktický výchozí bod pro týmy, které chtějí komplexní pokrytí kvality v Rustu bez nadměrného inženýrství:

yaml

# .github/workflows/quality.yml
name: Code Quality and Security

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt

      - name: Check formatting
        run: cargo fmt -- --check

      - name: Clippy (treat warnings as errors)
        run: cargo clippy -- -D warnings

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable

      - name: Install security tools
        run: |
          cargo install cargo-audit
          cargo install cargo-deny

      - name: Dependency audit
        run: cargo audit --deny warnings

      - name: License and policy check
        run: cargo deny check

  verify:
    runs-on: ubuntu-latest
    # Scheduled or manually triggered, not on every push
    if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: miri

      - name: Miri on unsafe modules
        run: cargo +nightly miri test --package my-unsafe-crate

Který nástroj byste měli použít? Průvodce rozhodováním

Zahájení nového projektu v RustuClippy + rustfmt + cargo-audit. Konfigurovatelné za méně než pět minut, zachycuje většinu problémů s kvalitou a bezpečností, se kterými se týmy setkávají.

Produkční služba s externími závislostmiPřidejte funkci „cargo-deny“ pro dodržování licencí a vynucování zásad dodavatelského řetězce nad rámec CVE.

Knihovní bedna s nebezpečnými vnitřnostmiPřidejte Miri do testovací sady pro moduly obsahující nebezpečný kód. Spouštějte Rudru podle plánu.

Bezpečnostně kritický nebo kryptografický kódPro nejdůležitější funkce napište Kaniho ověřovací metody. Pokud má tým odborné znalosti formálních metod, zvažte Creusota nebo Prustiho.

Organizace zaměřená na bezpečnostPřidejte Semgrep s vlastními pravidly pro bezpečnostní zásady organizace a navíc auditovatelný náklad v release buildech.

Neustálý přehled o větším týmuSonarCloud pro sledování trendů, dekoraci pull requestů a ověření kvality spolu s nástroji s otevřeným zdrojovým kódem.

Polyglot podnikové prostředí kde Rust interaguje s COBOLem, Javou nebo jinými staršími jazyky: nástroje Rustu pro jednomy jazyky nevidí přes hranice jazyků. SMART TS XL poskytuje mezijazykovou analýzu, která pokrývá celý systém.

Když se statická analýza Rust setká s podnikovými systémy

Rust se stále častěji používá pro nové služby v organizacích, které také provozují COBOL, Javu, PL/I nebo RPG na mainframe nebo starších platformách. V těchto prostředích se statická analýza vymyká tomu, co dokáže vidět jakýkoli nástroj specifický pro Rust. Mikroslužba v Rustu může volat program v COBOLu, zapisovat do sdílené databáze nebo zpracovávat události generované starším dávkovým systémem. Analýza kvality a závislostí, která je pro podnikového architekta důležitá, zahrnuje všechny tyto systémy současně.

SMART TS XL Tuto mezeru řeší analýzou závislostí mezi jazyky v celém portfoliu aplikací. Zatímco Clippy a cargo-audit vidí pouze Rust, SMART TS XL mapuje, jak služba Rust závisí na sdílených datových strukturách, starších programech a podnikových API a jaký by byl dopad změny kterékoli z těchto závislostí. Díky tomu je nástrojem volby pro analýza dopadu a plánování modernizace starších systémů v prostředích, kde je Rust jen jedním z mnoha jazyků.

Pro týmy, které postupně zavádějí Rust v rámci větší podnikové kódové základny, SMART TS XLJe statická analýza kódu poskytuje strukturální přehled potřebný k pochopení toho, jak komponenty Rustu zapadají do většího systému, než se provedou změny, které by mohly ovlivnit komponenty napsané v jiných jazycích. Jak bylo zkoumáno v kontextu grafy závislostí a riziko aplikaceMapování celé struktury závislostí před rozšířením systému je to, co odlišuje změny, které probíhají hladce, od těch, které způsobují selhání v komponentách, které nikdo nepomyslel na testování.

Vrstvený přístup je pointou

Statická analýza v Rustu není rozhodnutí o jednom nástroji. Je to vrstvená disciplína, která začíná tím, co vám kompilátor poskytne zdarma, a rozšiřuje se směrem ven na základě rizikového profilu vašeho kódu. Clippy a rustfmt jsou základ. cargo-audit je neobchodovatelný pro jakýkoli projekt s externími závislostmi. Miri patří do jakéhokoli projektu s nebezpečným kódem. Kani a nástroje pro formální ověřování jsou určeny pro funkce, u kterých je chyba nepřijatelná.

Týmy, které to zvládnou správně, integrují statickou analýzu do vývojového cyklu: Clippy inline v editoru, cargo-audit v každém spuštění CI a Miri v noční jobu, který zachytí to, co samotné testy nedokážou. Výsledkem není jen méně chyb. Je to druh jistoty v kódové základně, která umožňuje týmům rychle provádět změny s vědomím, že analytické vrstvy mezi vývojářem a produkčním prostředím fungují správně.