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...
|
||||
|
||||
- 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"
|
||||
|
||||
// The extra `data` parameter is for if you want to append to an existing
|
||||
// parameters object.
|
||||
module.exports = function(string) {
|
||||
if (string === "" || string == null) return {}
|
||||
if (string.charAt(0) === "?") string = string.slice(1)
|
||||
|
|
@ -29,9 +27,17 @@ module.exports = function(string) {
|
|||
}
|
||||
level = counters[key]++
|
||||
}
|
||||
// Disallow direct prototype pollution
|
||||
else if (level === "__proto__") break
|
||||
if (isValue) cursor[level] = value
|
||||
else if (cursor[level] == null) cursor[level] = isNumber ? [] : {}
|
||||
cursor = cursor[level]
|
||||
else {
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -97,4 +97,16 @@ o.spec("parseQueryString", function() {
|
|||
var data = parseQueryString("a=1&b=2&a=3")
|
||||
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