Open jackfromeast opened 1 year ago
Sorry, I do not understand the security vulnerability here. Could you please elaborate with a specific, working example? It is not clear to me how these gadgets help attackers leverage a prototype pollution vulnerability.
No problem!
In short, the existing prototype pollution vulnerability allows the attacker to inject any property with arbitrary value to the root prototype(Object.prototype
). However, for a more critical outcome like RCE instead of DoS, the attacker needs the program to load the polluted value from the root prototype through undefined
property lookups. And, this polluted value must then flow to execution sinks (e.g., the Function constructor and eval function) through the program's data flow.
Taking Gadget 1 (code, value) as an example, let's assume there is a prototype pollution vulnerability in the application that allows the attacker to inject the 'code' property into the root prototype. In the compilation stage of the 'node-blade' module, specifically at line 332 in 'compiler.js', the expression 'attr[i].code' initiates a property lookup through the prototype chain. Since attr[i]
does not contain a 'code' property of its own, the lookup proceeds up the prototype chain and returns the attacker's polluted value instead of 'undefined'. Then, the polluted value will be pushed to the buffer and become part of the template function body, which will be further executed.
else
varAttrs += "," + JSON.stringify(i) + ":{v:" + attrs[i].code +
(attrs[i].escape ? ",e:1" : "") +
(i == "class" && attrs[i].append ?
",a:" + JSON.stringify(attrs[i].append): "") + "}";
}
if(varAttrs.length > 0)
this._pushOff(ns + ".r.attrs({" + varAttrs.substr(1) + "}, " + ns + ");");
In this case, you can rewrite attrs[i].code
to attrs[i].hasOwnProperty('code')? attrs[i].code: undefined
, if you don't intentionally want load property from its prototype chain. Another way is to create a pure empty object (doesn't contain __proto__
property by default) for the items in attrs
array by using Object.create(null);
I see now. Thanks for clarifying!
Hi there!
I've identified several prototype pollution gadgets within the
node-blade
template engine that could potentially be leveraged by attackers to achieve remote code execution via prototype pollution vulnerabilities.In light of the findings, I kindly request your confirmation of these potential issues to improve the security of the JavaScript ecosystem. We would greatly appreciate any steps taken to address them and we stand ready to submit a pull request on the GitHub repository to help improve the security for all users of your excellent work.
Root Cause
The existence of these gadgets can be attributed to a specific programming practice. When checking for the presence of a property within an object variable, the lookup scope isn't explicitly defined. In JavaScript, the absence of a defined lookup scope prompts a search up to the root prototype (Object.prototype). This could potentially be under the control of an attacker if other prototype pollution vulnerabilities are present within the application.
Some vulnerable coding patterns are as follows.
Impact
If the application server is using the
node-blade
as the backend template engine, and there is another prototype pollution vulnerability in the application, then the attacker could leverage the found gadgets in thenode-blade
template engine to escalate the prototype pollution to remote code execution.Proof of Concept
Below, I present a Proof of Concept (PoC) to demonstrate the gadgets that I've recently identified in
node-blade@3.3.1
Gadget 1
Gadget 2
Gadget 3
Gadget 4
Gadget 5
Gadget 6
General Suggested Fix
To mitigate this issue, I recommend constraining the property lookup to the current object variable. Here are two general strategies:
Utilize the hasOwnProperty method, especially when there's no need to traverse the prototype chain.
Alternatively, consider using
Object.create(null)
to create a truly empty object, which won't include the__proto__
property.By adopting these measures, we can effectively prevent the potential exploitation of prototype pollution vulnerabilities.
Reference
Here is the reference link where a similar security issue has been found in
ejs
template engine: https://github.com/mde/ejs/pull/601