diff --git a/Cargo.lock b/Cargo.lock index 7b166258..094d2221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -955,7 +955,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.7", + "webpki-roots 1.0.10", ] [[package]] @@ -2091,7 +2091,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 1.0.7", + "webpki-roots 1.0.10", ] [[package]] @@ -2176,9 +2176,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.15" +version = "0.103.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" +checksum = "4443b1b6d39d7c663139942cc4558262562d2c84123bb6282ef177009ca8b281" dependencies = [ "ring", "rustls-pki-types", @@ -3097,14 +3097,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.7", + "webpki-roots 1.0.10", ] [[package]] name = "webpki-roots" -version = "1.0.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +checksum = "1c1c8e20c8a38fc7d65abfe74eb7280e4aa667e8eec8bc84996d2874810748d9" dependencies = [ "rustls-pki-types", ] diff --git a/scripts/audit-rust.mjs b/scripts/audit-rust.mjs index f1928b73..6b0e0ec2 100644 --- a/scripts/audit-rust.mjs +++ b/scripts/audit-rust.mjs @@ -6,6 +6,17 @@ import { fileURLToPath } from 'node:url' const advisoryDatabaseUrl = 'https://github.com/RustSec/advisory-db.git' +// Informational "unmaintained" notices only, never a vulnerability. Each entry +// names the dependency that pulls it in, so it can be dropped once that moves. +export const acceptedUnmaintainedAdvisories = [ + // zvariant, zbus_names and zvariant_derive were folded into zbus 6. They reach + // us only through ashpd 0.13 (Linux screencast portal), which still depends on + // zbus 5. Remove these once an ashpd release on zbus 6 is adopted. + { id: 'RUSTSEC-2026-0370', crate: 'zvariant', via: 'ashpd 0.13 -> zbus 5' }, + { id: 'RUSTSEC-2026-0371', crate: 'zbus_names', via: 'ashpd 0.13 -> zbus 5' }, + { id: 'RUSTSEC-2026-0372', crate: 'zvariant_derive', via: 'ashpd 0.13 -> zbus 5' } +] + export function rustAuditCommands({ databasePath, databaseExists }) { const refresh = databaseExists ? ['git', ['-C', databasePath, 'pull', '--ff-only', '--quiet']] @@ -15,7 +26,18 @@ export function rustAuditCommands({ databasePath, databaseExists }) { return [ refresh, ['cargo', ['fetch', '--locked']], - ['cargo', ['audit', '--db', databasePath, '--no-fetch', '--deny', 'warnings']] + [ + 'cargo', + [ + 'audit', + '--db', + databasePath, + '--no-fetch', + '--deny', + 'warnings', + ...acceptedUnmaintainedAdvisories.flatMap(({ id }) => ['--ignore', id]) + ] + ] ] } diff --git a/scripts/lib/audit-rust.test.mjs b/scripts/lib/audit-rust.test.mjs index 3741a236..62914573 100644 --- a/scripts/lib/audit-rust.test.mjs +++ b/scripts/lib/audit-rust.test.mjs @@ -1,13 +1,22 @@ import assert from 'node:assert/strict' import test from 'node:test' -import { rustAuditCommands } from '../audit-rust.mjs' +import { acceptedUnmaintainedAdvisories, rustAuditCommands } from '../audit-rust.mjs' + +const ignored = [ + '--ignore', + 'RUSTSEC-2026-0370', + '--ignore', + 'RUSTSEC-2026-0371', + '--ignore', + 'RUSTSEC-2026-0372' +] test('Rust audit clones a fresh database through system Git before auditing offline', () => { assert.deepEqual(rustAuditCommands({ databasePath: '/cache/rustsec', databaseExists: false }), [ ['git', ['clone', '--quiet', 'https://github.com/RustSec/advisory-db.git', '/cache/rustsec']], ['cargo', ['fetch', '--locked']], - ['cargo', ['audit', '--db', '/cache/rustsec', '--no-fetch', '--deny', 'warnings']] + ['cargo', ['audit', '--db', '/cache/rustsec', '--no-fetch', '--deny', 'warnings', ...ignored]] ]) }) @@ -15,6 +24,18 @@ test('Rust audit fast-forwards its cached database before auditing offline', () assert.deepEqual(rustAuditCommands({ databasePath: '/cache/rustsec', databaseExists: true }), [ ['git', ['-C', '/cache/rustsec', 'pull', '--ff-only', '--quiet']], ['cargo', ['fetch', '--locked']], - ['cargo', ['audit', '--db', '/cache/rustsec', '--no-fetch', '--deny', 'warnings']] + ['cargo', ['audit', '--db', '/cache/rustsec', '--no-fetch', '--deny', 'warnings', ...ignored]] ]) }) + +test('Rust audit ignores only the named unmaintained notices, each with its source', () => { + for (const advisory of acceptedUnmaintainedAdvisories) { + assert.match(advisory.id, /^RUSTSEC-\d{4}-\d{4}$/) + assert.ok(advisory.crate, `${advisory.id} names its crate`) + assert.ok(advisory.via, `${advisory.id} names the dependency that pulls it in`) + } + assert.deepEqual( + acceptedUnmaintainedAdvisories.map(({ id }) => id), + ['RUSTSEC-2026-0370', 'RUSTSEC-2026-0371', 'RUSTSEC-2026-0372'] + ) +})