Checksum-only data can pass a requested version check
Description
A requested version can be accepted when the decoded payload is empty. This affects DecodeBuilder::with_check and DecodeBuilder::as_cb58.
Steps to Reproduce
With bs58 0.5.1 and the check and cb58 features enabled, run these assertions. Their success reproduces the discrepancy:
assert_eq!(bs58::decode("3QJmnh").with_check(Some(93)).into_vec(), Ok(vec![]));
assert_eq!(bs58::decode("45PJLL").as_cb58(Some(120)).into_vec(), Ok(vec![]));
Expected Behavior
The API promises to use the supplied version in verification. A requested version requires a nonempty payload whose first byte is that version, so these checksum-only inputs should be rejected.
Actual Behavior
Each input contains only the four checksum bytes of an empty unversioned payload. When the payload is empty, the decoder compares the first checksum byte to the requested version and returns an empty payload if they match. Consequently, success with a requested version does not guarantee that the returned data contains that version; callers relying on that property can accept malformed versioned input.
Environment
bs58 0.5.1 with check and cb58.
Additional Context
See upstream issue #132.
Change history
- v1 · created · 2026-11-03 03:48 UTC
{ "title": "Checksum-only data can pass a requested version check", "body": "## Description\n\nA requested version can be accepted when the decoded payload is empty. This affects `DecodeBuilder::with_check` and `DecodeBuilder::as_cb58`.\n\n## Steps to Reproduce\n\nWith bs58 0.5.1 and the `check` and `cb58` features enabled, run these assertions. Their success reproduces the discrepancy:\n\n```rust\nassert_eq!(bs58::decode(\"3QJmnh\").with_check(Some(93)).into_vec(), Ok(vec![]));\nassert_eq!(bs58::decode(\"45PJLL\").as_cb58(Some(120)).into_vec(), Ok(vec![]));\n```\n\n## Expected Behavior\n\nThe API promises to use the supplied version in verification. A requested version requires a nonempty payload whose first byte is that version, so these checksum-only inputs should be rejected.\n\n## Actual Behavior\n\nEach input contains only the four checksum bytes of an empty unversioned payload. When the payload is empty, the decoder compares the first checksum byte to the requested version and returns an empty payload if they match. Consequently, success with a requested version does not guarantee that the returned data contains that version; callers relying on that property can accept malformed versioned input.\n\n## Environment\n\nbs58 0.5.1 with `check` and `cb58`.\n\n## Additional Context\n\nSee [upstream issue #132](https://github.com/Nullus157/bs58-rs/issues/132).", "validity": "reported", "upstream_status": "not_reported" } - v2 · link_added · 2026-11-03 03:51 UTC
{ "id": "fca196dd-f72c-4bf3-ae99-22cd5200aee0", "kind": "issue", "url": "https://github.com/Nullus157/bs58-rs/issues/132", "edit_version": 1 } - v3 · edited · 2026-11-03 03:51 UTC
{ "evidence_url": "https://github.com/MasWag/crate-proofs/blob/1c8a2741db2110c65d2457d36723612560bbe5f4/bs58/0.5.1/evidence/reproduce-findings/src/main.rs", "upstream_status": "reported_upstream", "edit_version": 2 }