Mitä ovat templaatit?
Vanhanaikaiset web-sovellukset rakensivat (ja osittain rakentavat yhä) HTML-vastauksia tämän kaltaisesti.
html = "<h1>Tervetuloa, " + nimi + "</h1>
return html
Tämän kaltainen HTML-rakennus on paitsi kankeaa, myös hirvittävän turvatonta. Tällaisiin sovelluksiin on yleensä aika helppo injektioida hyökkääjän omaa HTML/JavaScript-koodia, joka johtaa XSS-haavoittuvuuksiin.
Modernimpi lähestymistapa on käyttää templaatteja. Templaatit ovat erillisiä HTML-tiedostoja, jotka ovat osittain myös kooditiedostoja. Templaatille annetaan sitten haluttu data ja templaatti rakentaa HTML:n. Tässä koodissa ei ole haavoittuvuutta, koska templaatti osaa rakentaa HTML:ää turvallisesti niin, ettei ole väliä, mitä hyökkääjä on nimeksi syöttänyt, se ei muodostu vaarallisesti osaksi HTML-rakennetta.
template = "<h1>Tervetuloa, {{nimi}}</h1>"
return render_template(template, nimi=nimi)
Templaatti-injektio
Templaatti-injektiohaavoittuvuus on hyvin samankaltainen perinteisen HTML-injektion kanssa (josta seuraa XSS-haavoittuvuus), mutta huomattavasti vakavampi, koska toisin kuin HTML (joka suoritetaan selaimessa), templaatit suoritetaan koodina palvelimen päässä ennen kuin templaatin suorituksen seurauksena rakennettu HTML palautetaan selaimelle.
Tässä on esimerkki haavoittuvasta Flask-sovelluksesta, joka käyttää Jinja2-templaattimoottoria virheellisesti, antaen käyttäjän syötteen vaikuttaa itse templaattiin, eikä vain templaatille annettavaan dataan, kuten olisi pitänyt.
if request.method == 'POST':
name = request.form['name']
template = f'<h1>Tervetuloa, { name }!</h1>'
return render_template_string(template)
else:
template = '''
<form method="POST">
<label for="name">Nimi:</label>
<input type="text" name="name" id="name">
<button type="submit">Lähetä</button>
</form>
'''
return render_template_string(template)
Haavoittuvuuden havaitseminen
Pythonin JInja2 ei suinkaan ole ainoa templaattimoottori, vaan niitä on monta ja eri ohjelmointikielille. Lähes kaikkia templaattimoottoreita kuitenkin yhdistää syntaksi, jossa kahdet kaarisulut suorittavat lausekkeen, kuten vaikkapa kirjoittavat muuttujan tai laskevat laskun.
Perinteinen tapa havaita templaatti-injektioita on siis syöttää {{7*7}} syötteessä ja katsoa että palauttaako sovellus HTML:ssä "49" samalla kohdalla. Tämä on lähes varma merkki templaatti-injektiosta.
Kokeillaan:
Haavoittuvuuden hyväksikäyttö
Templaatti-injektiot johtavat lähes aina siihen, että hyökkääjä pääsee suorittamaan mielivaltaista koodia sovelluspalvelimella (RCE, Remote Code Execution). Se, että miten koodin suoritukseen asti päästään vaihtelee aika paljon ohjelmointikielestä ja templaattimoottorista riippuen. Tutustumme näihin tässä kurssilla.
Templaatti-injektioilta on helppo välttyä. Ei tarvitse muuta kuin pitää templaatti täysin staattisena niin, ettei itse templaattiin voi vaikuttaa millään tavalla. Pelkästään templaatin dataan saa vaikuttaa, ei rakenteeseen.
Kaikki dynaamisesti rakennetut templaatit ovat vaaranpaikka.
Valmis ryhtymään eettiseksi hakkeriksi?
Aloita jo tänään.
Hakatemian jäsenenä saat rajoittamattoman pääsyn Hakatemian moduuleihin, harjoituksiin ja työkaluihin, sekä pääset discord-kanavalle jossa voit pyytää apua sekä ohjaajilta että muilta Hakatemian jäseniltä.