Cross-site scripting (untuk selanjutnya akan disebut sebagai XSS) merupakan celah keamanan (security vulnerability) yang biasa ditemukan di aplikasi berbasis web. Celah keamanan ini memungkinkan penyerang memasukkan (inject) kode tertentu yang bersifat client-side (misalnya JavaScript, CSS). Kode yang di-inject oleh penyerang tersebut akan dilihat dan dijalankan juga oleh pengguna lain. Akibat dari celah keamanan ini cukup bervariasi, mulai dari sekedar mengganggu, merusak tampilan web, hingga pencurian data seperti cookie.
Contoh halaman web yang memiliki celah keamanan ini bisa dilihat di sini.
Pertama, coba isikan sesuatu secara normal (misalnya nama = alvin, komentar = hello world). Apa yang terjadi? Tentu saja tidak ada masalah. Nama dan komentar akan muncul sesuai dengan apa yang diinputkan.
Sekarang, coba isikan komentar yang ‘sedikit aneh’. Masukkan komentar yang berisi tag HTML, misalnya sebagai berikut:
Halo... ini contoh teks <b>bold</b> dan <u>underline</b>...
Apa yang terjadi? Komentar Anda muncul seperti ini:
Halo… ini contoh teks bold dan underline.
Nah, kode HTML yang kita sisipkan diproses oleh browser. Cobalah minta teman Anda untuk membuka halaman tersebut (dari komputer lain). Maka ia akan memperoleh hasil yang sama. Ini berarti si penyerang (dalam contoh ini adalah kita) berhasil meng-inject-kan kode buatannya. Hal seperti ini yang disebut celah keamanan Cross-Site Scripting. Ini harusnya tidak boleh terjadi. Bayangkan jika si penyerang menyisipkan kode berikut:
Halo...
<script type="text/javascript">
window.onload = function() {
document.getElementsByTagName("body")[0].innerHTML = '<h1>This web is hacked!</h1>';
}
</script>
Atau komentar berikut yang sangat mengganggu pengguna lain (pengguna lain akan mendapatkan alert/popup yang tidak pernah berakhir):
<script type="text/javascript">
while (true) {
alert('Sekarang jam ' + (new Date()).toUTCString());
}
</script>
Atau mungkin seperti ini:
Web ini bagus.
<script type="text/javascript">
if (confirm('Tapi sayang ada celah keamanannya! Klik OK untuk mempelajari celah keamanan tsb!')) {
document.location.href = 'http://www.muhammadalvin.net/2012/01/mengenal-cross-site-scripting/';
}
</script>
Yang mengarahkan pengguna ke halaman lain.
Cara mengatasinya cukup sederhana. Jika menggunakan PHP, tambahkan htmlentities() sebelum menampilkan hasil inputan dari pengguna. Misalnya kode berikut:
echo 'Nama : ' . $nama;
Diubah menjadi:
echo 'Nama : ' . htmlentities($nama);
Pastikan Anda menggunakan fungsi tersebut di setiap bagian yang bertugas menampilkan hasil inputan dari pengguna.
Buat yang ingin tahu secara detail tentang XSS, simak pembahasan berikut.
Andaikan Anda membuat halaman HTML (index.html) berikut:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Demo Cross-Site Scripting</title> </head> <body> <form action="hasil.php" method="post"> <p><label for="nama">Nama:</label><br /> <input type="text" name="nama" id="nama" /></p> <p><label for="komentar">Komentar:</label><br /> <textarea name="komentar" id="komentar" cols="40" rows="5"></textarea></p> <p><input type="submit" value="Kirim" /></p> </form> </body> </html>
Kemudian halaman PHP berikut (hasil.php) yang bertugas memproses hasil input dari halaman index.html:
<?php $nama = (isset($_POST['nama']) ? $_POST['nama'] : ''); $komentar = (isset($_POST['komentar']) ? $_POST['komentar'] : ''); echo '<p>Nama:<br />' . $nama . '</p>'; echo '<p>Komentar:<br />' . $komentar . '</p>';
Saat Anda menjalankan index.html, akan muncul sebuah form dengan dua field. Jika Anda mengisi nama dengan test dan komentar dengan hello world, maka ketika di-submit (dengan menekan tombol Kirim), hasil.php akan memprosesnya sebagai berikut:
$nama = (isset($_POST['nama']) ? $_POST['nama'] : ''); // maka $nama berisi: test $komentar = (isset($_POST['komentar']) ? $_POST['komentar'] : ''); // dan $komentar berisi: hello world echo '<p>Nama:<br />' . $nama . '</p>'; // sesuai dengan nilai di variabel $nama di atas, // maka akan di-echo: <p>Nama:<br />test</p> echo '<p>Komentar:<br />' . $komentar . '</p>'; // sesuai dengan nilai di variabel $komentar di atas, // maka akan di-echo: <p>Komentar:<br />hello world</p>
Di sini tidak ada masalah. Jika Anda coba jalankan, maka hasil sesuai dengan yang diharapkan.
Masalah muncul ketika misalnya komentar yang dimasukkan adalah ini adalah contoh teks <b>bold</b>. Halaman hasil.php akan memprosesnya sebagai berikut:
$komentar = (isset($_POST['komentar']) ? $_POST['komentar'] : ''); // $komentar berisi: ini adalah contoh teks <b>bold</b> echo '<p>Komentar:<br />' . $komentar . '</p>'; // sesuai dengan nilai di variabel $komentar di atas, // maka akan di-echo: <p>Komentar:<br />ini adalah contoh teks <b>bold</b></p>
Browser tidak pernah tau bahwa ini adalah contoh teks <b>bold</b> datangnya dari web developer yang membuat halaman atau dari isian pengguna yang iseng. Hasilnya, browser akan memproses kode HTML yang ada di dalamnya, sehingga akan menampilkan tulisan “bold” dalam keadaan bercetak tebal, hasil dari tag HTML <b> dan </b> tersebut.
Hal yang sama terjadi untuk JavaScript. Pengguna yang iseng bisa menyisipkan kode JavaScript yang diapit oleh tag HTML <script type=”text/javascript”> dan </script>. Hasilnya tentu saja kode JavaScript tersebut akan dijalankan oleh browser.
Cara mengatasinya adalah dengan meng-escape karakter-karakter spesial HTML, seperti:
- & menjadi &
- < menjadi <
- > menjadi >
- ” menjadi "
Anda bisa melakukan find-replace secara manual, atau menggunakan fungsi yang disediakan oleh bahasa pemrograman yang digunakan. Sebagai contoh fungsi htmlentities() yang disediakan oleh PHP.
Nah, XSS ini terjadi saat menampilkan sesuatu ke web browser. Celah keamanan sebaliknya, terjadi saat menyimpan sesuatu dari web browser (hasil input pengguna) ke database biasa dikenal dengan SQL injection. Selain kedua jenis tersebut, masih ada lagi celah keamanan yang lain, misalnya Cross-site Request Forgery (CSRF).
———-
Referensi:

Komentar Terkini