Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

xtask/tests/ossf_scorecard.rs

//! **What OpenSSF Scorecard reads in this tree, held here** (lane OSSF-NEXT, 2026-10-30).
//!
//! Scorecard runs nightly in local mode on the dwarves forge (`scorecard-holger`, results in
//! nordisk/ci-status). Two of its checks read files this repository controls:
//!
//! * **Vulnerabilities** runs osv-scanner over every `Cargo.lock` and honours an
//!   `osv-scanner.toml` in the lock's OWN directory (`[[IgnoredVulns]]`). That file is a
//!   second reader of the one triage policy, `deny.toml`'s `[advisories] ignore`, which the
//!   0-known-CVE gate (`cargo deny check advisories`) obeys. So every id an
//!   `osv-scanner.toml` ignores is ignored in `deny.toml` too, with a dated reason, and
//!   every `deny.toml` ignore is carried to the locks: one policy, never two that drift.
//!   Each entry also carries an `ignoreUntil`, so a triage expires and is looked at again.
//! * **Binary-Artifacts** flags a tracked file whose magic says executable or archive of
//!   code (ELF, PE, Mach-O, wasm, Java class, dex, crx, rpm, deb) or whose extension is one
//!   of its binary list (jar, whl, so, exe, …) when the content is not text. A fixture the
//!   tests need is made at test time from committed text instead.

use std::collections::BTreeSet;
use std::path::{Path, PathBuf};
use std::process::Command;

fn root() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR"))
        .parent()
        .expect("xtask has a parent")
        .to_path_buf()
}

/// The tracked files of the checkout (`git ls-files`), relative to the root.
fn tracked(root: &Path) -> Vec<String> {
    // A test of the tree it runs in: git is the authority on what is tracked.
    let out = Command::new("git")
        .arg("-C")
        .arg(root)
        .args(["ls-files", "-z"])
        .output()
        .expect("git ls-files runs");
    assert!(
        out.status.success(),
        "git ls-files: {}",
        String::from_utf8_lossy(&out.stderr)
    );
    out.stdout
        .split(|b| *b == 0)
        .filter(|s| !s.is_empty())
        .map(|s| String::from_utf8_lossy(s).into_owned())
        .collect()
}

/// The value of `key = "…"` on a line, if the line holds it.
fn quoted(line: &str, key: &str) -> Option<String> {
    let at = line.find(&format!("{key} ="))? + key.len() + 2;
    let rest = line[at..].trim_start().strip_prefix('"')?;
    Some(rest[..rest.find('"')?].to_owned())
}

/// `deny.toml`'s `[advisories] ignore` entries: (id, reason).
fn deny_ignores(text: &str) -> Vec<(String, String)> {
    let adv = text
        .split("[advisories]")
        .nth(1)
        .expect("deny.toml has [advisories]");
    let adv = adv.split("\n[").next().unwrap();
    adv.lines()
        .map(str::trim)
        .filter(|l| l.starts_with('{'))
        .filter_map(|l| Some((quoted(l, "id")?, quoted(l, "reason").unwrap_or_default())))
        .collect()
}

#[derive(Debug, Default)]
struct OsvIgnore {
    id: String,
    until: Option<String>,
    reason: Option<String>,
}

/// An `osv-scanner.toml`'s `[[IgnoredVulns]]` entries.
fn osv_ignores(text: &str) -> Vec<OsvIgnore> {
    let mut all: Vec<OsvIgnore> = Vec::new();
    for l in text.lines().map(str::trim) {
        if l.starts_with('#') {
            continue;
        }
        if l == "[[IgnoredVulns]]" {
            all.push(OsvIgnore::default());
            continue;
        }
        let Some(cur) = all.last_mut() else { continue };
        if let Some(v) = quoted(l, "id") {
            cur.id = v;
        } else if let Some(v) = quoted(l, "reason") {
            cur.reason = Some(v);
        } else if let Some(v) = l.strip_prefix("ignoreUntil =") {
            cur.until = Some(v.trim().to_owned());
        }
    }
    all
}

/// "YYYY-MM-DD" somewhere in `s`.
fn has_date(s: &str) -> bool {
    let b = s.as_bytes();
    b.windows(10).any(|w| {
        w.iter().enumerate().all(|(i, c)| {
            if i == 4 || i == 7 {
                *c == b'-'
            } else {
                c.is_ascii_digit()
            }
        }) && w.starts_with(b"20")
    })
}

/// ★ **The osv-scanner triage beside each lock is `deny.toml`'s triage, dated, and complete.**
#[test]
fn osv_scanner_triage_is_the_deny_toml_policy() {
    let root = root();
    let files = tracked(&root);
    let deny = deny_ignores(&std::fs::read_to_string(root.join("deny.toml")).expect("deny.toml"));
    let mut bad = Vec::new();
    for (id, reason) in &deny {
        if reason.trim().is_empty() || !has_date(reason) {
            bad.push(format!(
                "deny.toml ignores {id} without a dated reason (\"… Triaged YYYY-MM-DD …\")"
            ));
        }
    }
    let deny_ids: BTreeSet<&str> = deny.iter().map(|(i, _)| i.as_str()).collect();
    let locks: BTreeSet<&str> = files
        .iter()
        .filter(|f| f.ends_with("Cargo.lock"))
        .map(String::as_str)
        .collect();
    let mut carried: BTreeSet<String> = BTreeSet::new();
    let mut seen = 0;
    for f in files.iter().filter(|f| f.ends_with("osv-scanner.toml")) {
        seen += 1;
        let dir = f.strip_suffix("osv-scanner.toml").unwrap();
        if !locks.contains(format!("{dir}Cargo.lock").as_str()) {
            bad.push(format!("{f} sits beside no tracked Cargo.lock: osv-scanner reads it only in the lock's own directory"));
        }
        let text = std::fs::read_to_string(root.join(f)).unwrap();
        let entries = osv_ignores(&text);
        if entries.is_empty() {
            bad.push(format!("{f} ignores nothing"));
        }
        for e in entries {
            if !deny_ids.contains(e.id.as_str()) {
                bad.push(format!("{f} ignores {} but deny.toml does not: the cargo-deny gate and Scorecard would disagree", e.id));
            }
            if e.until.as_deref().is_none_or(|u| !has_date(u)) {
                bad.push(format!("{f}: {} has no ignoreUntil date", e.id));
            }
            if e.reason.as_deref().is_none_or(|r| r.trim().len() < 20) {
                bad.push(format!("{f}: {} has no reason", e.id));
            }
            carried.insert(e.id);
        }
    }
    if seen == 0 {
        bad.push(
            "no osv-scanner.toml is tracked: Scorecard counts every triaged advisory as open"
                .into(),
        );
    }
    for id in &deny_ids {
        if !carried.contains(*id) {
            bad.push(format!(
                "deny.toml ignores {id}, but no osv-scanner.toml beside a lock carries it"
            ));
        }
    }
    assert!(
        bad.is_empty(),
        "the triage policy has drifted:\n  {}",
        bad.join("\n  ")
    );
}

/// Scorecard's binary list (checks/raw/binary_artifact.go, v5.6.0).
const BINARY_EXT: &[&str] = &[
    "crx", "deb", "dex", "dey", "elf", "o", "a", "so", "macho", "iso", "class", "jar", "bundle",
    "dylib", "lib", "msi", "dll", "drv", "efi", "exe", "ocx", "pyc", "pyo", "par", "rpm", "wasm",
    "whl",
];

/// The magic numbers of the executable kinds on that list.
fn binary_magic(b: &[u8]) -> Option<&'static str> {
    let m: &[(&[u8], &str)] = &[
        (b"\x7fELF", "ELF"),
        (b"MZ", "PE/exe"),
        (b"\0asm", "wasm"),
        (b"\xca\xfe\xba\xbe", "Java class / Mach-O fat"),
        (b"\xfe\xed\xfa\xce", "Mach-O"),
        (b"\xfe\xed\xfa\xcf", "Mach-O"),
        (b"\xce\xfa\xed\xfe", "Mach-O"),
        (b"\xcf\xfa\xed\xfe", "Mach-O"),
        (b"dex\n", "dex"),
        (b"Cr24", "crx"),
        (b"\xed\xab\xee\xdb", "rpm"),
        (b"!<arch>\ndebian", "deb"),
    ];
    m.iter()
        .find(|(magic, _)| b.starts_with(magic))
        .map(|(_, k)| *k)
}

/// Scorecard's `isText`: no control byte but tab, CR and LF in the first KiB.
fn is_text(b: &[u8]) -> bool {
    let b = &b[..b.len().min(1024)];
    match std::str::from_utf8(b) {
        Ok(s) => s
            .chars()
            .all(|c| c >= ' ' || matches!(c, '\n' | '\t' | '\r')),
        Err(e) => {
            let ok = &b[..e.valid_up_to()];
            e.valid_up_to() + 4 > b.len()
                && std::str::from_utf8(ok)
                    .unwrap()
                    .chars()
                    .all(|c| c >= ' ' || matches!(c, '\n' | '\t' | '\r'))
        }
    }
}

/// ★ **The tree carries no binary artifact** (Scorecard Binary-Artifacts). The one exception
/// is named here with its reason: upstream bytes whose real signature is the test.
#[test]
fn the_tree_carries_no_binary_artifact() {
    // `sampleproject 4.0.0`'s wheel as PyPI serves it: its PEP 740 attestation (Sigstore,
    // pypa's release workflow) signs THESE bytes, and the pull-through and upload tests prove
    // a real wheel against it (and refuse it under the sdist's attestation). Rebuilt bytes
    // would carry no valid signature. One copy, in server-lib's pull-through fixtures.
    const KEPT: &[&str] = &[
        "server/lib/tests/fixtures/pull_through/pypi/files/sampleproject-4.0.0-py3-none-any.whl",
    ];
    let root = root();
    let mut bad = Vec::new();
    for f in tracked(&root) {
        if KEPT.contains(&f.as_str()) {
            continue;
        }
        let Ok(mut file) = std::fs::File::open(root.join(&f)) else {
            continue;
        };
        let mut head = vec![0u8; 1024];
        let n = std::io::Read::read(&mut file, &mut head).unwrap_or(0);
        head.truncate(n);
        if head.is_empty() {
            continue;
        }
        let ext = Path::new(&f)
            .extension()
            .and_then(|e| e.to_str())
            .unwrap_or("")
            .to_ascii_lowercase();
        if let Some(kind) = binary_magic(&head) {
            bad.push(format!("{f}: {kind}"));
        } else if BINARY_EXT.contains(&ext.as_str()) && !is_text(&head) {
            bad.push(format!("{f}: a .{ext} that is not text"));
        }
    }
    assert!(
        bad.is_empty(),
        "binary artifacts in the tree (make them at test time from text):\n  {}",
        bad.join("\n  ")
    );
}