Client Side Prototype Pollution
Reading time: 9 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Entdeckung mit automatischen Werkzeugen
Die Werkzeuge https://github.com/dwisiswant0/ppfuzz, https://github.com/kleiton0x00/ppmap und https://github.com/kosmosec/proto-find können verwendet werden, um Prototype Pollution-Schwachstellen zu finden.
Darüber hinaus können Sie auch die Browsererweiterung PPScan verwenden, um die Seiten, die Sie zugreifen, automatisch auf Prototype Pollution-Schwachstellen zu scannen.
Debugging, wo eine Eigenschaft verwendet wird
// Stop debugger where 'potentialGadget' property is accessed
Object.defineProperty(Object.prototype, "potentialGadget", {
__proto__: null,
get() {
console.trace()
return "test"
},
})
Finden der Ursache für Prototype Pollution
Sobald eine Prototype Pollution-Sicherheitsanfälligkeit von einem der Tools identifiziert wurde und der Code nicht übermäßig komplex ist, können Sie die Sicherheitsanfälligkeit finden, indem Sie nach Schlüsselwörtern wie location.hash
, decodeURIComponent
oder location.search
in den Chrome Developer Tools suchen. Dieser Ansatz ermöglicht es Ihnen, den anfälligen Abschnitt des JavaScript-Codes genau zu bestimmen.
Für größere und komplexere Codebasen besteht eine einfache Methode zur Entdeckung des anfälligen Codes aus den folgenden Schritten:
- Verwenden Sie ein Tool, um eine Sicherheitsanfälligkeit zu identifizieren und ein Payload zu erhalten, das darauf ausgelegt ist, eine Eigenschaft im Konstruktor festzulegen. Ein Beispiel, das von ppmap bereitgestellt wird, könnte so aussehen:
constructor[prototype][ppmap]=reserved
. - Setzen Sie einen Haltepunkt in der ersten Zeile des JavaScript-Codes, die auf der Seite ausgeführt wird. Aktualisieren Sie die Seite mit dem Payload und pausieren Sie die Ausführung an diesem Haltepunkt.
- Während die JavaScript-Ausführung pausiert ist, führen Sie das folgende Skript in der JS-Konsole aus. Dieses Skript signalisiert, wann die 'ppmap'-Eigenschaft erstellt wird, und hilft dabei, ihren Ursprung zu lokalisieren:
function debugAccess(obj, prop, debugGet = true) {
var origValue = obj[prop]
Object.defineProperty(obj, prop, {
get: function () {
if (debugGet) debugger
return origValue
},
set: function (val) {
debugger
origValue = val
},
})
}
debugAccess(Object.prototype, "ppmap")
- Navigieren Sie zurück zum Sources-Tab und wählen Sie „Script-Ausführung fortsetzen“. Das JavaScript wird wie erwartet weiter ausgeführt, und die 'ppmap'-Eigenschaft wird verschmutzt. Die Verwendung des bereitgestellten Snippets erleichtert die Identifizierung des genauen Standorts, an dem die 'ppmap'-Eigenschaft verschmutzt wird. Durch die Untersuchung des Call Stack können verschiedene Stacks beobachtet werden, in denen die Verschmutzung aufgetreten ist.
Bei der Entscheidung, welchen Stack man untersuchen soll, ist es oft nützlich, Stacks zu zielen, die mit JavaScript-Bibliotheksdateien verbunden sind, da die Prototypverschmutzung häufig innerhalb dieser Bibliotheken auftritt. Identifizieren Sie den relevanten Stack, indem Sie seine Verbindung zu Bibliotheksdateien untersuchen (sichtbar auf der rechten Seite, ähnlich einem bereitgestellten Bild zur Orientierung). In Szenarien mit mehreren Stacks, wie auf den Zeilen 4 und 6, ist die logische Wahl der Stack auf Zeile 4, da er das erste Auftreten der Verschmutzung darstellt und damit die Wurzelursache der Schwachstelle ist. Ein Klick auf den Stack führt Sie zum verwundbaren Code.
Finden von Script-Gadgets
Das Gadget ist der Code, der missbraucht wird, sobald eine PP-Schwachstelle entdeckt wird.
Wenn die Anwendung einfach ist, können wir nach Schlüsselwörtern wie srcdoc/innerHTML/iframe/createElement
suchen und den Quellcode überprüfen, um festzustellen, ob er zu einer JavaScript-Ausführung führt. Manchmal finden die erwähnten Techniken möglicherweise überhaupt keine Gadgets. In diesem Fall zeigt eine reine Quellcodeüberprüfung einige schöne Gadgets wie das folgende Beispiel.
Beispiel für das Finden eines PP-Gadgets im Mithil-Bibliothekscode
Überprüfen Sie diesen Bericht: https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challenge-author-writeup/
Neukompilierung von Payloads für verwundbare Bibliotheken
- https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#prototype-pollution
- https://github.com/BlackFan/client-side-prototype-pollution
HTML-Sanitizer-Umgehung über PP
Diese Forschung zeigt PP-Gadgets, die verwendet werden können, um die Sanitierungen zu umgehen, die von einigen HTML-Sanitizer-Bibliotheken bereitgestellt werden:
- sanitize-html
.png)
- dompurify
.png)
- Closure
<!-- from https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/ -->
<script>
Object.prototype['* ONERROR'] = 1;
Object.prototype['* SRC'] = 1;
</script>
<script src=https://google.github.io/closure-library/source/closure/goog/base.js></script>
<script>
goog.require('goog.html.sanitizer.HtmlSanitizer');
goog.require('goog.dom');
</script>
<body>
<script>
const html = '<img src onerror=alert(1)>';
const sanitizer = new goog.html.sanitizer.HtmlSanitizer();
const sanitized = sanitizer.sanitize(html);
const node = goog.dom.safeHtmlToNode(sanitized);
document.body.append(node);
</script>
Neue Tools & Automatisierung (2023–2025)
- Burp Suite DOM Invader (v2023.6) – PortSwigger hat einen speziellen Prototype-pollution Tab hinzugefügt, der automatisch Parameternamen (z.B.
__proto__
,constructor.prototype
) verändert und verschmutzte Eigenschaften an Sink-Punkten innerhalb der Browsererweiterung erkennt. Wenn ein Gadget ausgelöst wird, zeigt DOM Invader den Ausführungsstapel und die genaue Zeile, in der die Eigenschaft dereferenziert wurde, wodurch manuelles Breakpoint-Suchen überflüssig wird. Kombinieren Sie es mit dem oben bereits gezeigten Snippet "Break on property access", um schnell von source → sink zu pivotieren. - protoStalker – ein Open-Source Chrome DevTools Plug-in (veröffentlicht 2024), das Prototypketten in Echtzeit visualisiert und Schreibvorgänge an global gefährlichen Schlüsseln wie
onerror
,innerHTML
,srcdoc
,id
usw. kennzeichnet. Nützlich, wenn Sie nur ein Produktionsbundle haben und den Build-Schritt nicht instrumentieren können. - ppfuzz 2.0 (2025) – das Tool unterstützt jetzt ES-Module, HTTP/2 und WebSocket-Endpunkte. Der neue
-A browser
Modus startet eine headless Chromium-Instanz und enumeriert automatisch Gadget-Klassen, indem DOM-APIs bruteforced werden (siehe Abschnitt unten).
Jüngste Forschung zu Prototype-Pollution Gadgets (2022–2025)
Mitte 2023 veröffentlichten Forscher von PortSwigger ein Papier, das zeigt, dass browser-eigene Objekte in zuverlässige XSS-Gadgets verwandelt werden können, sobald sie verschmutzt sind. Da diese Objekte auf jeder Seite vorhanden sind, können Sie Ausführung erlangen, selbst wenn der Anwendungscode des Ziels die verschmutzte Eigenschaft nie berührt.
Beispiel-Gadget (funktioniert in allen Evergreen-Browsern ≥ 2023-04):
<script>
// Source (e.g. https://victim/?__proto__[href]=javascript:alert(document.domain))
// For demo we just pollute manually:
Object.prototype.href = 'javascript:alert(`polluted`)' ;
// Sink – URL() constructor implicitly reads `href`
new URL('#'); // breaks into JS; in Chrome you get an alert, Firefox loads "javascript:" URL
</script>
Andere nützliche globale Gadgets, die nach der Verschmutzung bestätigt wurden (getestet 2024-11):
Gadget-Klasse | Leseeigenschaft | Erreichte Primitive |
---|---|---|
Notification | title | alert() über Benachrichtigungsklick |
Worker | name | JS-Ausführung in dediziertem Worker |
Image | src | Traditionelles onerror XSS |
URLSearchParams | toString | DOM-basiertes Open Redirect |
Siehe das PortSwigger-Papier für die vollständige Liste von 11 Gadgets und eine Diskussion über Sandbox-Umgehungen.
Bemerkenswerte Client-Side PP CVEs (2023-2025)
- DOMPurify ≤ 3.0.8 – CVE-2024-45801 Ein Angreifer könnte
Node.prototype.after
vor der Initialisierung des Sanitizers verschmutzen, wodurch das SAFE_FOR_TEMPLATES-Profil umgangen und zu gespeichertem XSS geführt wird. Der Anbieter hat dies durch die Verwendung vonObject.hasOwn()
-Überprüfungen undObject.create(null)
für interne Maps gepatcht. - jQuery 3.6.0-3.6.3 – CVE-2023-26136 / CVE-2023-26140
extend()
könnte auf manipulierten Objekten, die vonlocation.hash
stammen, verwendet werden, wodurch willkürliche Eigenschaften inObject.prototype
im Browsing-Kontext eingeführt werden. - sanitize-html < 2.8.1 (2023-10) Prototype Pollution Eine bösartige Attributliste wie
{"__proto__":{"innerHTML":"<img/src/onerror=alert(1)>"}}
umging die Erlaubenliste.
Selbst wenn die verwundbare Bibliothek nur auf dem Client lebt, ist das resultierende XSS immer noch aus der Ferne über reflektierte Parameter, postMessage-Handler oder gespeicherte Daten, die später gerendert werden, ausnutzbar.
Moderne Abwehrmaßnahmen
- Friere das globale Prototyp früh ein (idealerweise als erstes Skript):
Object.freeze(Object.prototype);
Object.freeze(Array.prototype);
Object.freeze(Map.prototype);
Sei dir bewusst, dass dies Polyfills brechen könnte, die auf späte Erweiterungen angewiesen sind.
2. Verwende structuredClone()
anstelle von JSON.parse(JSON.stringify(obj))
oder Community "deepMerge"-Schnipseln – es ignoriert Setter/Getters und durchläuft nicht die Prototypenkette.
3. Wenn du wirklich eine tiefe Zusammenführungsfunktionalität benötigst, wähle lodash ≥ 4.17.22 oder deepmerge ≥ 5.3.0, die eingebaute Prototypen-Sanierung haben.
4. Füge eine Content-Security-Policy mit script-src 'self'
und einem strengen nonce hinzu. Während CSP nicht alle Gadgets stoppen wird (z.B. location
-Manipulation), blockiert es die Mehrheit der innerHTML
-Senken.
Referenzen
-
https://portswigger.net/research/widespread-prototype-pollution-gadgets
-
https://snyk.io/blog/dompurify-prototype-pollution-bypass-cve-2024-45801/
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.