Skip to content

Commit fd9765b

Browse files
committed
JS: Add qhelp
1 parent 0c715f7 commit fd9765b

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
<p>
8+
Most JavaScript objects inherit the properties of the built-in <code>Object.prototype</code> object.
9+
If an attacker is be able to modify <code>Object.prototype</code>, they can tamper with the
10+
application logic and often escalate to remote code execution or cross-site scripting.
11+
</p>
12+
13+
<p>
14+
One way to cause prototype pollution is through use of an unsafe <em>merge</em> or <em>extend</em> function
15+
to recursively copy properties from an untrusted source object.
16+
Such a call can modify any object reachable from the destination object, and
17+
the built-in <code>Object.prototype</code> is usually reachable through the special properties
18+
<code>__proto__</code> and <code>constructor.prototype</code>.
19+
An attacker can abuse this by sending an object with these property names and thereby modify <code>Object.prototype</code>.
20+
</p>
21+
</overview>
22+
23+
<recommendation>
24+
<p>
25+
Update your library dependencies in order to use a safe version of the <em>merge</em> or <em>extend</em> function.
26+
If you library has no fixed version, switch to another library.
27+
</p>
28+
</recommendation>
29+
30+
<example>
31+
<p>
32+
In the example below, the untrusted value <code>req.query.prefs</code> is parsed as JSON
33+
and then copied into a new object:
34+
</p>
35+
36+
<sample src="examples/PrototypePollution1.js"/>
37+
38+
<p>
39+
Prior to lodash 4.17.11 this would be vulnerable to prototype pollution. An attacker could send
40+
the value <code>{"constructor": {"prototype": {"xxx": true}}}</code> to inject <code>xxx</code>
41+
in <code>Object.prototype</code>.
42+
Fix this by updating the lodash version:
43+
</p>
44+
45+
<sample src="examples/PrototypePollution_fixed.json"/>
46+
47+
<p>
48+
Note that some web frameworks, such as Express, parse query parameters using extended URL-encoding
49+
by default.
50+
In this case, the application may be vulnerable even if not using <code>JSON.parse</code>.
51+
The example below would also be susceptible to prototype pollution:
52+
</p>
53+
54+
<sample src="examples/PrototypePollution2.js"/>
55+
</example>
56+
57+
<references>
58+
<li>Prototype pollution attacks:
59+
<a href="https://hackerone.com/reports/380873">lodash</a>,
60+
<a href="https://hackerone.com/reports/454365">jQuery</a>,
61+
<a href="https://hackerone.com/reports/381185">extend</a>,
62+
<a href="https://hackerone.com/reports/430291">just-extend</a>,
63+
<a href="https://hackerone.com/reports/381194">merge.recursive</a>,
64+
</li>
65+
<li>Express:
66+
<a href="https://expressjs.com/en/api.html#express.urlencoded">urlencoded()</a>
67+
</li>
68+
</references>
69+
</qhelp>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
app.get('/news', (req, res) => {
2+
let prefs = lodash.merge({}, JSON.parse(req.query.prefs));
3+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
app.get('/news', (req, res) => {
2+
let prefs = lodash.merge({}, {
3+
topic: req.query.topic
4+
});
5+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"lodash": "^4.17.11"
4+
}
5+
}

0 commit comments

Comments
 (0)