Pre-releases are not distinguished from releases
Describe the bug
axum-core here: https://github.com/rustsec/advisory-db/pull/1417#discussion_r967847287 has the below pattern:
0.2.7 (and anything below) is vulnerable
0.2.8 (and anything until 0.3.0.rc.1) is not vulnerable
0.3.0-rc.1 is vulnerable
0.3.0-rc.2 (and anything above) is not vulnerable
0.3.0 eventually as real release will not be expected to be vulnerable
It's a problematic pattern as we cannot currently say for various reasons including resulting implicit arithmetric:
patched = [">= 0.2.8, < 0.3.0", ">= 0.3.0"]
Mostly above fails due to overlapping versions and we went through several iterations -
Until we came up with something like this:
patched = ["= 0.2.8", "= 0.3.0", ">= 0.3.1"]
unaffected = ["= 0.3.0-rc.2"]
Tested with cargo audit: https://github.com/rustsec/advisory-db/pull/1417#discussion_r968323230 - works as expected
And tested with cargo deny: https://github.com/rustsec/advisory-db/pull/1417#discussion_r968346951 - doesn't recognise 0.3.0-rc.1 as affected
Some pre-releases / release candidates can be vulnerable and are different to official releases.
e.g. in case of axum-core there is vulnerability that affects 0.3.0-rc.1 where as 0.3.0=rc.2 and future non-pre-release 0.3.0 will be patched but cargo deny doesn't distinguish between pre-release and release.
cargo deny does not flag 0.3.0-rc.1 as expected but at least it doesn't cause other side effects and does a warning of some sort:
2022-09-12 12:18:20 [WARN] unable to find a config path, falling back to default config
warning[A009]: advisory for a crate with a pre-release was skipped as it matched a patch
┌─ /home/foobar/gg/play/zz/tesssts/Cargo.lock:2:1
│
2 │ axum-core 0.3.0-rc.1 registry+https://github.com/rust-lang/crates.io-index
│ -------------------------------------------------------------------------- pre-release crate
│
= ID: RUSTSEC-2022-4000
= Advisory: https://rustsec.org/advisories/RUSTSEC-2022-4000
= Satisfied version requirement: =0.3.0
= axum-core v0.3.0-rc.1
└── tesssts v0.1.0
advisories ok
cargo audit flags it correctly:
$ grep axum-core Cargo.toml; cargo audit -n
axum-core = "=0.3.0-rc.1"
Loaded 457 security advisories (from /home/foobar/.cargo/advisory-db)
Scanning Cargo.lock for vulnerabilities (18 crate dependencies)
Crate: axum-core
Version: 0.3.0-rc.1
Title: No default limit put on request bodies
Date: 2022-08-31
ID: RUSTSEC-2022-4000
URL: https://rustsec.org/advisories/RUSTSEC-2022-4000
Solution: Upgrade to =0.2.8 OR =0.3.0 OR >=0.3.1
Dependency tree:
axum-core 0.3.0-rc.1
└── tesssts 0.1.0
error: 1 vulnerability found!
To Reproduce
Dummy crate that relies with release-candidate:
[dependencies]
axum-core = "=0.3.0-rc.1"
Then mock advisory with how we would mark it in advisory db:
patched = ["= 0.2.8", "= 0.3.0", ">= 0.3.1"]
unaffected = ["= 0.3.0-rc.2"]
Expected behavior
cargo deny should flag advisory on 0.3.0-rc.1 when patched is pinned = 0.3.0 and 0.3.0-rc.1 has not been marked as unaffected
Additional context
I don't think we've added advisories that need to match pre-releases but worth an ask if cargo deny could support this I guess ?
Discussing here in depth what to do with pre-releases in general: https://github.com/rustsec/rustsec/issues/690
I'd accept a patch for this because I know the handling is incorrect for pre-releases, but they are also annoying and relatively rare so it's IMO low priority.
Yeah cool just figuring what our canonical is and happy to send a patch after,
I've asked others around preferences but I think: https://github.com/rustsec/rustsec/issues/690#issuecomment-1243822287 may end up as our intended canonical.
e.g. in axum-core we would end up with 0.3.0 being patched with simply this:
patched = [">= 0.2.8, < 0.3.0-rc.1", ">= 0.3.0-rc.2"]
As our canonical would be lexicographic and pre-releases would be "lesser than" release:
0.3.0-rc.1
0.3.0.rc.2
0.3.0 <-- release after pre-releases is "greater" than pre-releases so the above pattern works to catch it in "patched"
Problem would be in any tooling where SemVer 0.3.0 is seen as "before" or "lesser than" pre-releases e.g. in a case where 0.3.0 would still end up as vulnerable if patched is marked as >= 0.3.0-rc.2 so I'm just going around to inquire some preferences / expectations.