From 0a0432d463e5cd6186b6b750550b68c46838a207 Mon Sep 17 00:00:00 2001 From: ericbfriday <29077621+ericbfriday@users.noreply.github.com> Date: Fri, 29 May 2026 23:42:53 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20Prototype=20Pollution=20in=20label=20definitions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the `labels` dictionary initialization in `luaparse.js` to use a null-prototype object (`Object.create(null)`). This prevents Prototype Pollution vulnerabilities that could be triggered by parsing malicious Lua code defining labels with names of built-in prototype properties (like `__proto__`, `constructor`, or `hasOwnProperty`). --- .jules/sentinel.md | 4 ++++ luaparse.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..1f6247b --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2025-02-14 - Fix Prototype Pollution in label dictionary +**Vulnerability:** The Lua parser tracked label names using standard object literals (`labels: {}`). This allowed malicious Lua code defining labels named `__proto__`, `constructor`, or `hasOwnProperty` to manipulate the object's prototype properties or crash the parser during lookups due to unexpected inherited properties, leading to Prototype Pollution / DoS. +**Learning:** Dictionaries storing arbitrary user-defined identifiers in parsers must never be standard object literals, as they are susceptible to prototype inheritance issues when keys collide with built-ins. +**Prevention:** Always initialize dictionaries meant to store arbitrary keys using null-prototype objects (`Object.create(null)`). Use fallback `Object.create ? Object.create(null) : {}` if very old environment support is required. diff --git a/luaparse.js b/luaparse.js index a6bcbac..7f60102 100644 --- a/luaparse.js +++ b/luaparse.js @@ -1674,7 +1674,7 @@ FullFlowContext.prototype.pushScope = function (isLoop) { var scope = { - labels: {}, + labels: Object.create ? Object.create(null) : {}, locals: [], deferredGotos: [], isLoop: !!isLoop