Skip to content

Commit 8e51b00

Browse files
committedJul 11, 2021
fix(parse): prevent overwriting __proto__ in parseQuery()
issue was reported privately by @NewEraCracker
1 parent 46c8ac0 commit 8e51b00

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed
 

‎src/URI.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,10 @@
658658
// no "=" is null according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters
659659
value = v.length ? URI.decodeQuery(v.join('='), escapeQuerySpace) : null;
660660

661-
if (hasOwn.call(items, name)) {
661+
if (name === '__proto__') {
662+
// ignore attempt at exploiting JavaScript internals
663+
continue;
664+
} else if (hasOwn.call(items, name)) {
662665
if (typeof items[name] === 'string' || items[name] === null) {
663666
items[name] = [items[name]];
664667
}
@@ -751,7 +754,10 @@
751754
var t = '';
752755
var unique, key, i, length;
753756
for (key in data) {
754-
if (hasOwn.call(data, key)) {
757+
if (key === '__proto__') {
758+
// ignore attempt at exploiting JavaScript internals
759+
continue;
760+
} else if (hasOwn.call(data, key)) {
755761
if (isArray(data[key])) {
756762
unique = {};
757763
for (i = 0, length = data[key].length; i < length; i++) {

‎test/test.js

+8
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,10 @@
418418
equal(u.query(), 'foo&foo=bar', 'search: foo&foo=bar');
419419
equal(JSON.stringify(u.query(true)), JSON.stringify({foo: [null, 'bar']}), 'parsed query: {foo:[null, "bar"]}');
420420

421+
u.search('__proto__=hasOwnProperty&__proto__=eviltwin&uuid');
422+
equal(u.query(), '__proto__=hasOwnProperty&__proto__=eviltwin&uuid', 'search: __proto__=hasOwnProperty&__proto__=eviltwin&uuid');
423+
equal(JSON.stringify(u.query(true)), '{"uuid":null}', 'parsed query: {uuid: null}');
424+
421425
// parsing empty query
422426
var t;
423427
t = u.query('?').query(true);
@@ -931,6 +935,10 @@
931935
u.setQuery('some value', 'must be encoded because of = and ? and #');
932936
equal(u.query(), 'some+value=must+be+encoded+because+of+%3D+and+%3F+and+%23', 'encoding');
933937
equal(u.query(true)['some value'], 'must be encoded because of = and ? and #', 'decoding');
938+
939+
u.query('?foo=bar');
940+
u.setQuery('__proto__', 'hasOwnProperty');
941+
equal(u.query(), 'foo=bar', 'set __proto__');
934942
});
935943
test('addQuery', function() {
936944
var u = URI('?foo=bar');

‎test/urls.js

+48
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,54 @@ var urls = [{
21312131
idn: false,
21322132
punycode: false
21332133
}
2134+
}, {
2135+
name: '__proto__ in query',
2136+
url: 'http://www.example.org/?__proto__=hasOwnProperty&__proto__=eviltwin&uuid',
2137+
parts: {
2138+
protocol: 'http',
2139+
username: null,
2140+
password: null,
2141+
hostname: 'www.example.org',
2142+
port: null,
2143+
path: '/',
2144+
query: '__proto__=hasOwnProperty&__proto__=eviltwin&uuid',
2145+
fragment: null
2146+
},
2147+
accessors: {
2148+
protocol: 'http',
2149+
username: '',
2150+
password: '',
2151+
port: '',
2152+
path: '/',
2153+
query: '__proto__=hasOwnProperty&__proto__=eviltwin&uuid',
2154+
fragment: '',
2155+
resource: '/?__proto__=hasOwnProperty&__proto__=eviltwin&uuid',
2156+
authority: 'www.example.org',
2157+
origin: 'http://www.example.org',
2158+
userinfo: '',
2159+
subdomain: 'www',
2160+
domain: 'example.org',
2161+
tld: 'org',
2162+
directory: '/',
2163+
filename: '',
2164+
suffix: '',
2165+
hash: '',
2166+
search: '?__proto__=hasOwnProperty&__proto__=eviltwin&uuid',
2167+
host: 'www.example.org',
2168+
hostname: 'www.example.org'
2169+
},
2170+
is: {
2171+
urn: false,
2172+
url: true,
2173+
relative: false,
2174+
name: true,
2175+
sld: false,
2176+
ip: false,
2177+
ip4: false,
2178+
ip6: false,
2179+
idn: false,
2180+
punycode: false
2181+
}
21342182
}
21352183
];
21362184

0 commit comments

Comments
 (0)
Please sign in to comment.