GHunter: Universal Prototype Pollution Gadgets in JavaScript Runtimes
Eric Cornelissen, Mikhail Shcherbakov, Musard Balliu
TL;DR
Prototype pollution enables attacker-controlled modifications to JavaScript prototypes, potentially triggering gadgets that lead to severe impacts such as ACE and SSRF across runtime environments. GHunter advances this field with a semi-automated, dynamic taint-analysis pipeline that instruments V8-based runtimes (Node.js and Deno), collects undefined property accesses from runtime test suites, simulates pollution, and traces tainted values to native sinks and crashes; manual validation via SARIF then yields concrete gadget discoveries. The study identifies 123 exploitable gadgets (56 in Node.js, 67 in Deno) and 301/418 gadget candidates, outperforming prior static/dynamic approaches and informing defense guidelines for gadget mitigation and prototype pollution. The results highlight the practical risk, including a high-severity CVE tied to gadget fixes, and emphasize the need for principled, runtime-level mitigations and gadget-aware security practices to reduce the attack surface. Overall, GHunter provides a scalable framework for cataloging universal gadgets and lays groundwork for defensive tooling in runtime ecosystems.
Abstract
Prototype pollution is a recent vulnerability that affects JavaScript code, leading to high impact attacks such as arbitrary code execution. The vulnerability is rooted in JavaScript's prototype-based inheritance, enabling attackers to inject arbitrary properties into an object's prototype at runtime. The impact of prototype pollution depends on the existence of otherwise benign pieces of code (gadgets), which inadvertently read from attacker-controlled properties to execute security-sensitive operations. While prior works primarily study gadgets in third-party libraries and client-side applications, gadgets in JavaScript runtime environments are arguably more impactful as they affect any application that executes on these runtimes. In this paper we design, implement, and evaluate a pipeline, GHunter, to systematically detect gadgets in V8-based JavaScript runtimes with prime focus on Node.js and Deno. GHunter supports a lightweight dynamic taint analysis to automatically identify gadget candidates which we validate manually to derive proof-of-concept exploits. We implement GHunter by modifying the V8 engine and the targeted runtimes along with features for facilitating manual validation. Driven by the test suites of Node.js and Deno, we use GHunter in a study of gadgets in these runtimes. We identified a total of 56 new gadgets in Node.js and 67 gadgets in Deno, pertaining to vulnerabilities such as arbitrary code execution (19), privilege escalation (31), path traversal (13), and more. Moreover, we systematize, for the first time, existing mitigations for prototype pollution and gadgets in terms of development guidelines. We collect a list of vulnerable applications and revisit the fixes through the lens of our guidelines. Through this exercise, we identified one high-severity CVE leading to remote code execution, which was due to incorrectly fixing a gadget.
