{"id":"GHSA-7gcf-g7xr-8hxj","summary":"serde_with: KeyValueMap serialization panics on empty sequence or map entries","details":"### Summary\n\nThe public `KeyValueMap` serializer assumes that each mapped element has at least one field or item to use as the map key, but it subtracts `1` from the caller-visible length before validating that assumption. An application that serializes attacker-controlled data through `#[serde_as(as = \"KeyValueMap\u003c_\u003e\")]` can be crashed by an empty inner sequence or map entry.\n\n### Details\n\nThe affected public surface includes:\n\n- Serialization of `#[serde_as(as = \"KeyValueMap\u003c_\u003e\")]` values through `serde_json::to_string` or any other Serde serializer`\n- Public `KeyValueMap` conversions for sequence and map-backed entries`\n\nThe root cause is: The `KeyValueMap` serializer preallocating `Vec::with_capacity(len - 1)` or `Vec::with_capacity(len.unwrap_or(17) - 1)` before checking that the element actually contains the required first key field or item.\n\nThe vulnerable data/control flow is: attacker-controlled empty entry -\u003e `serde_json::to_string` -\u003e `KeyValueMap\u003cTAs\u003e::serialize_as` -\u003e `SeqAsMapSerializer::{serialize_seq,serialize_map}` -\u003e `Vec::with_capacity(len - 1)` or `Vec::with_capacity(len.unwrap_or(17) - 1)` -\u003e panic\n\nRelevant source locations:\n\n- `serde_with/src/key_value_map.rs:590`\n- `serde_with/src/key_value_map.rs:599`\n- `serde_with/src/key_value_map.rs:613`\n- `serde_with/src/key_value_map.rs:632`\n- `serde_with/src/key_value_map.rs:648`\n\n### PoC\n\n```rust\n/*\n[dependencies]\nserde = {version = \"*\", features = [\"derive\"]}\nserde_with = \"*\"\nserde_json = \"*\"\n*/\n\nuse serde::Serialize;\nuse serde_with::{serde_as, KeyValueMap};\n\n#[derive(Serialize)]\n#[serde(transparent)]\nstruct Seq(Vec\u003cString\u003e);\n\n#[serde_as]\n#[derive(Serialize)]\n#[serde(transparent)]\nstruct KVMap {\n    #[serde_as(as = \"KeyValueMap\u003c_\u003e\")]\n    foo: Vec\u003cSeq\u003e,\n}\n\nfn main() {\n    let value = KVMap {\n        foo: vec![Seq(Vec::new())],\n    };\n    let _ = serde_json::to_string(&value).unwrap();\n}\n```\n\n### Impact\n\nA local attacker who can trigger serialization of attacker-controlled data through `KeyValueMap` can terminate the process, causing a denial of service.","modified":"2026-09-10T03:51:10.897685062Z","published":"2026-07-15T22:41:01Z","database_specific":{"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-07-15T22:41:01Z","nvd_published_at":null,"cwe_ids":["CWE-20"]},"references":[{"type":"WEB","url":"https://github.com/jonasbb/serde_with/security/advisories/GHSA-7gcf-g7xr-8hxj"},{"type":"WEB","url":"https://github.com/jonasbb/serde_with/pull/966"},{"type":"WEB","url":"https://github.com/jonasbb/serde_with/commit/c8a1d820ea25df01692b367058d587343e199389"},{"type":"PACKAGE","url":"https://github.com/jonasbb/serde_with"},{"type":"WEB","url":"https://github.com/jonasbb/serde_with/compare/v2.2.0...v2.3.0"},{"type":"WEB","url":"https://github.com/jonasbb/serde_with/releases/tag/v3.21.0"}],"affected":[{"package":{"name":"serde_with","ecosystem":"crates.io","purl":"pkg:cargo/serde_with"},"ranges":[{"type":"SEMVER","events":[{"introduced":"2.3.0"},{"fixed":"3.21.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-7gcf-g7xr-8hxj/GHSA-7gcf-g7xr-8hxj.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N"}]}