Prevent prototype pollution while parsing query strings (#2494)
* Prevent prototype pollution while parsing query strings * Update changelog [skip ci]
This commit is contained in:
parent
48e7fd1711
commit
97fa1788c2
3 changed files with 23 additions and 4 deletions
|
|
@ -17,6 +17,7 @@
|
||||||
### Upcoming...
|
### Upcoming...
|
||||||
|
|
||||||
- Ensure vnodes are removed correctly in the face of `onbeforeremove` resolving after new nodes are added ([#2492](https://github.com/MithrilJS/mithril.js/pull/2492) [@isiahmeadows](https://github.com/isiahmeadows))
|
- Ensure vnodes are removed correctly in the face of `onbeforeremove` resolving after new nodes are added ([#2492](https://github.com/MithrilJS/mithril.js/pull/2492) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||||
|
- Fix prototype pollution vulnerability in `m.parseQueryString` ([#2494](https://github.com/MithrilJS/mithril.js/pull/2494) [@isiahmeadows](https://github.com/isiahmeadows))
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
"use strict"
|
"use strict"
|
||||||
|
|
||||||
// The extra `data` parameter is for if you want to append to an existing
|
|
||||||
// parameters object.
|
|
||||||
module.exports = function(string) {
|
module.exports = function(string) {
|
||||||
if (string === "" || string == null) return {}
|
if (string === "" || string == null) return {}
|
||||||
if (string.charAt(0) === "?") string = string.slice(1)
|
if (string.charAt(0) === "?") string = string.slice(1)
|
||||||
|
|
@ -29,9 +27,17 @@ module.exports = function(string) {
|
||||||
}
|
}
|
||||||
level = counters[key]++
|
level = counters[key]++
|
||||||
}
|
}
|
||||||
|
// Disallow direct prototype pollution
|
||||||
|
else if (level === "__proto__") break
|
||||||
if (isValue) cursor[level] = value
|
if (isValue) cursor[level] = value
|
||||||
else if (cursor[level] == null) cursor[level] = isNumber ? [] : {}
|
else {
|
||||||
cursor = cursor[level]
|
// Read own properties exclusively to disallow indirect
|
||||||
|
// prototype pollution
|
||||||
|
value = Object.getOwnPropertyDescriptor(cursor, level)
|
||||||
|
if (value != null) value = value.value
|
||||||
|
if (value == null) value = cursor[level] = isNumber ? [] : {}
|
||||||
|
}
|
||||||
|
cursor = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
|
||||||
|
|
@ -97,4 +97,16 @@ o.spec("parseQueryString", function() {
|
||||||
var data = parseQueryString("a=1&b=2&a=3")
|
var data = parseQueryString("a=1&b=2&a=3")
|
||||||
o(data).deepEquals({a: "3", b: "2"})
|
o(data).deepEquals({a: "3", b: "2"})
|
||||||
})
|
})
|
||||||
|
o("doesn't pollute prototype directly, censors `__proto__`", function() {
|
||||||
|
var prev = Object.prototype.toString
|
||||||
|
var data = parseQueryString("a=b&__proto__%5BtoString%5D=123")
|
||||||
|
o(Object.prototype.toString).equals(prev)
|
||||||
|
o(data).deepEquals({a: "b"})
|
||||||
|
})
|
||||||
|
o("doesn't pollute prototype indirectly, retains `constructor`", function() {
|
||||||
|
var prev = Object.prototype.toString
|
||||||
|
var data = parseQueryString("constructor%5Bprototype%5D%5BtoString%5D=123")
|
||||||
|
o(Object.prototype.toString).equals(prev)
|
||||||
|
o(data).deepEquals({a: "b"})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue