ParserPoison: From Schema to Shell in binary-parser

Maor Caplan
Jan 26, 2026
In the quest for performance, developers often turn to dynamic code generation. By "compiling" logic at runtime, applications can achieve blazing-fast speeds. However, as I discovered during a proactive security audit of widely used NPM libraries, if you don't sanitize the ingredients of that compilation, you're not just building a parser, you're building a backdoor.
I'm calling this discovery ParserPoison.
Auditing the Ecosystem
This research was part of a broader effort to identify architectural "sinkhole" patterns in popular JavaScript libraries, specifically focusing on those that handle binary data parsing for high-performance applications. Given that binary-parser sees nearly 700,000 annual downloads, it became a priority for a deep-dive source code review.
The objective was to identify instances where user controlled schemas could influence runtime code generation. Many developers assume that libraries provide implicit safety, but whenever the Function constructor is used to dynamically generate code, user input must be rigorously sanitized.
How the Poison Spreads
The vulnerability (CVE-2026-1245) exists because binary-parser compiles parser definitions into JavaScript functions using the new Function() constructor. While this approach is great for performance, the library was directly interpolating variable names and encoding parameters without sufficient sanitization.
1. Field Name Injection
When defining a parser field, the library takes the field name provided in the schema and drops it directly into the generated code string:
If an attacker provides a name like x; console.log("Hacked"); //, the generated function becomes:
2. Encoding Parameter Injection
A similar, even more potent vector exists in the string parsing logic. The encoding parameter is interpolated into a TextDecoder constructor call:
By providing a crafted encoding string, an attacker can break out of the string literal and inject arbitrary code. With a malicious encoding like utf8'); PAYLOAD; var x=(', the generated code becomes:
The injected payload executes, and var x=(' absorbs the remaining syntax to prevent errors.
Proving the Breach (The PoC)
To validate the blast radius, I crafted a Proof of Concept that escapes the parser logic to gain command execution on the host machine:
This confirmed that any application dynamically constructing parsers from untrusted schemas was vulnerable.


Hardening the Scope
The fix for ParserPoison is a lesson in secure library design: Never treat dynamic code templates as safe.
I recommended a strict allow-list approach for all strings intended for interpolation. The maintainer responded quickly, implementing input validation in version 2.3.0 to ensure that variable names conform to a safe identifier pattern (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/) and encoding parameters are checked against an explicit allow-list of valid encodings before they ever reach the compiler.
Final Thoughts
ParserPoison serves as a stark reminder that the most efficient code is often the most dangerous if left unguarded. As we continue to move toward high-performance, JIT-like compilation patterns in our libraries, proactive auditing of these dynamic "sinks" remains a critical line of defense for the open-source ecosystem.
Special thanks to Keichi Takahashi for the rapid fix and the CERT/CC team for coordinating the disclosure.
