mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
JS: Add qhelp
This commit is contained in:
69
javascript/ql/src/Security/CWE-400/PrototypePollution.qhelp
Normal file
69
javascript/ql/src/Security/CWE-400/PrototypePollution.qhelp
Normal file
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Most JavaScript objects inherit the properties of the built-in <code>Object.prototype</code> object.
|
||||
If an attacker is be able to modify <code>Object.prototype</code>, they can tamper with the
|
||||
application logic and often escalate to remote code execution or cross-site scripting.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
One way to cause prototype pollution is through use of an unsafe <em>merge</em> or <em>extend</em> function
|
||||
to recursively copy properties from an untrusted source object.
|
||||
Such a call can modify any object reachable from the destination object, and
|
||||
the built-in <code>Object.prototype</code> is usually reachable through the special properties
|
||||
<code>__proto__</code> and <code>constructor.prototype</code>.
|
||||
An attacker can abuse this by sending an object with these property names and thereby modify <code>Object.prototype</code>.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Update your library dependencies in order to use a safe version of the <em>merge</em> or <em>extend</em> function.
|
||||
If you library has no fixed version, switch to another library.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the example below, the untrusted value <code>req.query.prefs</code> is parsed as JSON
|
||||
and then copied into a new object:
|
||||
</p>
|
||||
|
||||
<sample src="examples/PrototypePollution1.js"/>
|
||||
|
||||
<p>
|
||||
Prior to lodash 4.17.11 this would be vulnerable to prototype pollution. An attacker could send
|
||||
the value <code>{"constructor": {"prototype": {"xxx": true}}}</code> to inject <code>xxx</code>
|
||||
in <code>Object.prototype</code>.
|
||||
Fix this by updating the lodash version:
|
||||
</p>
|
||||
|
||||
<sample src="examples/PrototypePollution_fixed.json"/>
|
||||
|
||||
<p>
|
||||
Note that some web frameworks, such as Express, parse query parameters using extended URL-encoding
|
||||
by default.
|
||||
In this case, the application may be vulnerable even if not using <code>JSON.parse</code>.
|
||||
The example below would also be susceptible to prototype pollution:
|
||||
</p>
|
||||
|
||||
<sample src="examples/PrototypePollution2.js"/>
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>Prototype pollution attacks:
|
||||
<a href="https://hackerone.com/reports/380873">lodash</a>,
|
||||
<a href="https://hackerone.com/reports/454365">jQuery</a>,
|
||||
<a href="https://hackerone.com/reports/381185">extend</a>,
|
||||
<a href="https://hackerone.com/reports/430291">just-extend</a>,
|
||||
<a href="https://hackerone.com/reports/381194">merge.recursive</a>,
|
||||
</li>
|
||||
<li>Express:
|
||||
<a href="https://expressjs.com/en/api.html#express.urlencoded">urlencoded()</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,3 @@
|
||||
app.get('/news', (req, res) => {
|
||||
let prefs = lodash.merge({}, JSON.parse(req.query.prefs));
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
app.get('/news', (req, res) => {
|
||||
let prefs = lodash.merge({}, {
|
||||
topic: req.query.topic
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user