CVE-2026-9521 Overview
CVE-2026-9521 affects the fraillt/bitsery C++ serialization library in versions up to and including 5.2.4. The flaw resides in the loadFromSharedState function within include/bitsery/ext/std_smart_ptr.h. The library performs improper validation of the specified input type when reconstructing shared polymorphic smart pointers during deserialization [CWE-20]. An attacker can trigger the issue remotely by supplying crafted serialized data to an application that consumes untrusted bitsery streams. Public disclosure of the exploit details has occurred, and the maintainer addressed the issue in version 5.2.5 via commit 66d16516e24893bebc1c8af52bf2fe9ad0735061.
Critical Impact
Remote attackers can supply crafted serialized payloads that bypass type validation in shared smart pointer reconstruction, leading to limited confidentiality, integrity, and availability impact in applications embedding bitsery.
Affected Products
- fraillt/bitsery versions up to and including 5.2.4
- C++ applications using include/bitsery/ext/std_smart_ptr.h for polymorphic shared pointer deserialization
- Downstream projects vendoring bitsery prior to release v5.2.5
Discovery Timeline
- 2026-05-26 - CVE-2026-9521 published to the National Vulnerability Database
- 2026-05-26 - Last updated in NVD database
Technical Details for CVE-2026-9521
Vulnerability Analysis
The vulnerability is an improper input validation issue in the deserialization path for shared polymorphic smart pointers. The loadFromSharedState template in std_smart_ptr.h reinterpreted a pointer stored in shared state directly to the requested element type. Because the library did not distinguish between polymorphic and non-polymorphic shared-state reconstruction, an attacker controlling the serialized payload could induce a type mismatch between the runtime object and the requested TElement cast.
Applications that deserialize untrusted bitsery streams containing shared pointers to polymorphic class hierarchies are exposed. The downstream impact depends on how the resulting std::shared_ptr<TElement> is used by host code, but the cast occurs without verifying that the stored object derives from the requested element type.
Root Cause
The root cause is a missing separation between polymorphic and non-polymorphic shared-pointer reload paths. A single loadFromSharedState handler performed a reinterpret_cast<TElement*> on the raw pointer pulled from shared state, with no validation that the stored type matched the expected element type. When polymorphic objects participated in shared state, the resulting std::shared_ptr aliased memory under an incorrect static type.
Attack Vector
Exploitation requires the target application to deserialize attacker-supplied bitsery data over a network channel, file, or IPC boundary. No authentication or user interaction is required at the library layer. The attacker crafts a serialized payload that references a shared polymorphic object, causing the vulnerable loadFromSharedState to materialize a std::shared_ptr<TElement> aliasing an object of an incompatible type.
state.obj = std::shared_ptr<TElement>(obj);
}
+ static void saveToSharedStatePolymorphic(TSharedState& state, T& obj)
+ {
+ state.obj = std::shared_ptr<TElement>(obj);
+ }
+
static void loadFromSharedState(TSharedState& state, T& obj)
{
// reinterpret_pointer_cast is only since c++17
- auto p = reinterpret_cast<TElement*>(state.obj.get());
+ auto v = state.obj.get();
+ auto p = reinterpret_cast<TElement*>(v);
+ obj = std::shared_ptr<TElement>(state.obj, p);
+ }
+
+ static void loadFromSharedStatePolymorphic(TSharedState& state, T& obj)
+ {
+ // TODO Fix pointer addresses in case objects are deserialized using
+ // different bases
+
+ // reinterpret_pointer_cast is only since c++17
+ auto v = state.obj.get();
+ auto p = reinterpret_cast<TElement*>(v);
obj = std::shared_ptr<TElement>(state.obj, p);
}
};
Source: GitHub Bitsery Commit 66d1651. The patch introduces a dedicated loadFromSharedStatePolymorphic path so polymorphic shared-state reconstruction is handled separately from the non-polymorphic case.
Detection Methods for CVE-2026-9521
Indicators of Compromise
- Applications linking against bitsery versions <= 5.2.4 that deserialize untrusted input over network or file boundaries.
- Unexpected crashes, type confusion errors, or memory corruption near calls into bitsery::ext::StdSmartPtr deserialization frames.
- Anomalous payload patterns targeting bitsery-encoded RPC or persistence formats containing shared polymorphic pointers.
Detection Strategies
- Perform a software composition analysis (SCA) scan to identify embedded copies of bitsery at or below version 5.2.4 across build artifacts and container images.
- Review source trees for direct use of loadFromSharedState in std_smart_ptr.h and confirm the library version in use.
- Inspect crash telemetry and core dumps for failures originating in shared smart pointer reload paths within bitsery.
Monitoring Recommendations
- Monitor application logs and crash reporting for deserialization errors in services that consume bitsery-encoded data from external sources.
- Track outbound and inbound traffic volumes on services that accept bitsery payloads to identify unusual deserialization activity.
- Alert on new third-party dependency drift that reintroduces vulnerable bitsery versions during builds.
How to Mitigate CVE-2026-9521
Immediate Actions Required
- Upgrade fraillt/bitsery to version 5.2.5 or later in all affected build pipelines and container images.
- Rebuild and redeploy any binaries that statically link or vendor bitsery to ensure the patched code is in effect.
- Audit application interfaces that accept bitsery-serialized data and restrict them to trusted callers until upgrades complete.
Patch Information
The fix is included in bitsery v5.2.5, released on 2025-10-09. The patch commit hash is 66d16516e24893bebc1c8af52bf2fe9ad0735061 and introduces a dedicated loadFromSharedStatePolymorphic handler for polymorphic shared smart pointer reconstruction. See the GitHub Bitsery Release Tag v5.2.5 and the GitHub Changelog for Bitsery for release notes.
Workarounds
- Restrict bitsery deserialization endpoints to authenticated, trusted peers via network controls and mutual TLS.
- Avoid passing untrusted serialized data through code paths that materialize shared polymorphic smart pointers until the upgrade is applied.
- Add input size and structure validation layers in front of bitsery decoders to reject malformed or oversized payloads.
# Update vendored dependency to the patched release
git -C third_party/bitsery fetch --tags
git -C third_party/bitsery checkout v5.2.5
# Verify the patch commit is present
git -C third_party/bitsery log --oneline | grep 66d16516e24893bebc1c8af52bf2fe9ad0735061
# Rebuild downstream artifacts
cmake --build build --clean-first
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


