NodeJS - __proto__ & prototype Pollution
Last updated
Last updated
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Voorwerpe in JavaScript is essensieel versamelings van sleutel-waarde pare, bekend as eienskappe. 'n Voorwerp kan geskep word met Object.create
met null
as 'n argument om 'n leë voorwerp te produseer. Hierdie metode stel die skepping van 'n voorwerp sonder enige geërfde eienskappe in staat.
'n Leë objek is soortgelyk aan 'n leë woordeboek, voorgestel as {}
.
In JavaScript is klasse en funksies nou verwant, met funksies wat dikwels as konstruktors vir klasse dien. Ten spyte van JavaScript se gebrek aan inheemse klasondersteuning, kan konstruktors klasgedrag naboots.
JavaScript stel die wysiging, toevoeging of verwydering van prototipe-attribuutte op runtime moontlik. Hierdie buigsaamheid stel die dinamiese uitbreiding van klasfunksies in staat.
Funksies soos toString
en valueOf
kan verander word om hul gedrag te verander, wat die aanpasbare aard van JavaScript se prototipesisteem demonstreer.
In prototipe-gebaseerde programmering word eienskappe/metodes geërf deur voorwerpe van klasse. Hierdie klasse word geskep deur eienskappe/metodes by 'n instansie van 'n ander klas of by 'n leë voorwerp te voeg.
Dit moet opgemerk word dat wanneer 'n eienskap by 'n voorwerp gevoeg word wat as die prototipe vir ander voorwerpe dien (soos myPersonObj
), die geërfde voorwerpe toegang tot hierdie nuwe eienskap verkry. Hierdie eienskap word egter nie outomaties vertoon nie, tensy dit eksplisiet opgeroep word.
JavaScript voorwerpe word gedefinieer deur sleutel-waarde pare en erf van die JavaScript Object prototipe. Dit beteken dat die wysiging van die Object prototipe alle voorwerpe in die omgewing kan beïnvloed.
Kom ons gebruik 'n ander voorbeeld om dit te illustreer:
Toegang tot die Object-prototipe is moontlik deur:
Deur eienskappe aan die Object-prototipe toe te voeg, sal elke JavaScript-objek hierdie nuwe eienskappe erf:
Vir 'n scenario waar __proto__
gebruik beperk is, is die aanpassing van 'n funksie se prototipe 'n alternatief:
Dit raak slegs voorwerpe wat van die Vehicle
konstruktors gemaak is, en gee hulle die beep
, hasWheels
, honk
, en isElectric
eienskappe.
Twee metodes om JavaScript voorwerpe globaal te beïnvloed deur middel van prototipe besoedeling sluit in:
Besoedeling van die Object.prototype
direk:
Besoedeling van die prototipe van 'n konstruksie vir 'n algemeen gebruikte struktuur:
Na hierdie operasies kan elke JavaScript-objek goodbye
en greet
metodes uitvoer.
In 'n scenario waar jy 'n spesifieke objek kan besmet en jy moet by Object.prototype
kom, kan jy daarna soek met iets soos die volgende kode:
Let daarop dat soos jy die eienskappe van voorwerpe in JS kan besoedel, as jy toegang het om 'n array te besoedel, kan jy ook waardes van die array besoedel wat deur indekse toeganklik is (let daarop dat jy nie waardes kan oorskryf nie, so jy moet indekse besoedel wat op een of ander manier gebruik word maar nie geskryf word nie).
Wanneer 'n HTML-element via JS gegenereer word, is dit moontlik om die innerHTML
attribuut te oorskryf om arbitraire HTML-kode te skryf. Idee en voorbeeld van hierdie skrywe.
'n Prototype besoedeling vind plaas weens 'n fout in die toepassing wat dit toelaat om eienskappe op Object.prototype
te oorskryf. Dit beteken dat omdat die meeste objekte hul eienskappe van Object.prototype
aflei
Die maklikste voorbeeld is om 'n waarde by 'n onbepaalde eienskap van 'n objek te voeg wat gaan nagegaan word, soos:
As die attribuut admin
is onbepaald is dit moontlik om 'n PP te misbruik en dit op True te stel met iets soos:
Die meganisme agter hierdie behels die manipulasie van eienskappe sodat, indien 'n aanvaller beheer het oor sekere insette, hulle die prototipe van alle voorwerpe in die aansoek kan wysig. Hierdie manipulasie behels tipies die instelling van die __proto__
eienskap, wat in JavaScript sinoniem is met die direkte wysiging van 'n voorwerp se prototipe.
Die voorwaardes waaronder hierdie aanval suksesvol uitgevoer kan word, soos uiteengesit in 'n spesifieke studie, sluit in:
Om 'n rekursiewe samesmelting uit te voer.
Om eienskappe te definieer op grond van 'n pad.
Om voorwerpe te kloon.
Ander payloads:
Vir verdere besonderhede, kyk na hierdie artikel In jQuery kan die $ .extend
funksie lei tot prototype besoedeling as die diep kopie kenmerk verkeerdelik gebruik word. Hierdie funksie word algemeen gebruik om voorwerpe te kloon of eienskappe van 'n standaard voorwerp te meng. egter, wanneer verkeerd geconfigureer, kan eienskappe wat bedoel is vir 'n nuwe voorwerp aan die prototipe toegeken word. Byvoorbeeld:
This kwesbaarheid, geïdentifiseer as CVE-2019–11358, illustreer hoe 'n diep kopie per ongeluk die prototipe kan verander, wat lei tot potensiële sekuriteitsrisiko's, soos ongeoorloofde admin toegang as eienskappe soos isAdmin
nagegaan word sonder behoorlike bestaan verifikasie.
Vir verdere besonderhede, kyk hierdie artikel
Lodash het soortgelyke prototipe besoedeling kwesbaarhede ondervind (CVE-2018–3721, CVE-2019–10744). Hierdie probleme is in weergawe 4.17.11 aangespreek.
Server-Side-Prototype-Pollution-Gadgets-Scanner: Burp Suite uitbreiding ontwerp om server-kant prototipe besoedeling kwesbaarhede in webtoepassings te ontdek en te analiseer. Hierdie gereedskap outomatiseer die proses van skandering van versoeke om potensiële prototipe besoedeling probleme te identifiseer. Dit benut bekende gadgets - metodes om prototipe besoedeling te benut om skadelike aksies uit te voer - met spesifieke fokus op Node.js biblioteke.
server-side-prototype-pollution: Hierdie uitbreiding identifiseer server kant prototipe besoedeling kwesbaarhede. Dit gebruik tegnieke wat beskryf word in die server side prototype pollution.
NodeJS gebruik uitgebreid Abstract Syntax Trees (AST) in JavaScript vir funksies soos sjabloon enjin en TypeScript. Hierdie afdeling verken die kwesbaarhede wat verband hou met prototipe besoedeling in sjabloon enjins, spesifiek Handlebars en Pug.
Die Handlebars sjabloon enjin is kwesbaar vir 'n prototipe besoedeling aanval. Hierdie kwesbaarheid ontstaan uit spesifieke funksies binne die javascript-compiler.js
lêer. Die appendContent
funksie, byvoorbeeld, voeg pendingContent
by as dit teenwoordig is, terwyl die pushSource
funksie pendingContent
na undefined
reset nadat die bron bygevoeg is.
Eksploitasiestap
Die eksploitasiestap benut die AST (Abstract Syntax Tree) wat deur Handlebars geproduseer word, volgens hierdie stappe:
Manipulasie van die Parser: Aanvanklik, die parser, via die NumberLiteral
node, afdwing dat waardes numeries is. Prototipe besoedeling kan dit omseil, wat die invoeging van nie-numeriese strings moontlik maak.
Hantering deur die Compiler: Die compiler kan 'n AST Object of 'n string sjabloon verwerk. As input.type
gelyk is aan Program
, word die invoer as vooraf-geparseer beskou, wat benut kan word.
Inspuiting van Kode: Deur manipulasie van Object.prototype
, kan 'n mens arbitrêre kode in die sjabloon funksie inspuit, wat kan lei tot afstandkode-uitvoering.
'n Voorbeeld wat die eksploitering van die Handlebars kwesbaarheid demonstreer:
Hierdie kode demonstreer hoe 'n aanvaller arbitrêre kode in 'n Handlebars-sjabloon kan inspuit.
Buite Verwysing: 'n Probleem rakende prototipe besoedeling is in die 'flat' biblioteek gevind, soos hier beskryf: Probleem op GitHub.
Buite Verwysing: Probleem rakende prototipe besoedeling in die 'flat' biblioteek
Voorbeeld van prototipe besoedeling uitbuiting in Python:
Pug, 'n ander sjabloon enjin, ondervind 'n soortgelyke risiko van prototipe besoedeling. Gedetailleerde inligting is beskikbaar in die bespreking oor AST-inspuiting in Pug.
Voorbeeld van prototipe besoedeling in Pug:
Om die risiko van prototipe besoedeling te verminder, kan die onderstaande strategieë toegepas word:
Objek Immutabiliteit: Die Object.prototype
kan onveranderlik gemaak word deur Object.freeze
toe te pas.
Invoer Validasie: JSON-invoere moet streng teen die aansoek se skema geverifieer word.
Veilige Samevoeg Funksies: Die onveilige gebruik van rekursiewe samevoeg funksies moet vermy word.
Prototipe-loos Objekte: Objekte sonder prototipe eienskappe kan geskep word met Object.create(null)
.
Gebruik van Map: In plaas van Object
, moet Map
gebruik word om sleutel-waarde pare te stoor.
Biblioteek Opdaterings: Sekuriteitsopdaterings kan ingesluit word deur gereeld biblioteke op te dateer.
Linter en Statiese Analise Gereedskap: Gebruik gereedskap soos ESLint met toepaslike plugins om prototipe besoedeling kwesbaarhede te ontdek en te voorkom.
Kode Hersienings: Voer deeglike kode hersienings uit om potensiële risiko's rakende prototipe besoedeling te identifiseer en te verhelp.
Sekuriteitsopleiding: Onderwys ontwikkelaars oor die risiko's van prototipe besoedeling en beste praktyke vir die skryf van veilige kode.
Gebruik van Biblioteke met Versigtigheid: Wees versigtig wanneer jy derdeparty biblioteke gebruik. Evalueer hul sekuriteitsposisie en hersien hul kode, veral dié wat objekte manipuleer.
Runtime Beskerming: Gebruik runtime beskermingsmeganismes soos om sekuriteitsgefokusde npm-pakkette te gebruik wat prototipe besoedeling aanvalle kan ontdek en voorkom.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)