Dapatkan info setiap update artikel! Subscribe Now!

Cara Mengamankan Website dari Celah XSS

XSS ini merupakan singkatan dari Cross-site Scripting. Yang mana teknik ini merupakan salah satu jenis serangan injeksi kode (Code Injection Attack).
Cara Mengamankan Website dari Celah XSS
Setelah membahas mengenai Celah SQL Injection, Bypass Admin, dan No redirect Admin Login. Kali ini kita akan membahas lagi salah satu celah pada website yang pastinya akan cukup berbahaya jika celah ini tetap dibiarkan. Pasalnya, teknik ini bisa dilakukan untuk membajak cookie pengguna suatu website yang selanjutnya bisa digunakan untuk membajak session pengguna. Jika saja cookie pengguna sudah berhasil didapatkan, maka si penyerang akan dengan mudah login ke halaman admin tanpa perlu melakukan proses login dengan benar.

Apa itu XSS?

XSS ini merupakan singkatan dari Cross-site Scripting. Yang mana teknik ini merupakan salah satu jenis serangan injeksi kode (Code Injection Attack). XSS dilakukan oleh penyerang dengan cara memasukkan kode HTML atau client script kode lainnya ke suatu website. Ada dua tipe XSS yaitu Reflected XSS dan Stored XSS.

Penjelasan sederhananya Reflected XSS adalah serangan dari sisi client dengan menginputkan kode HTML atau client script kode lainnya yang data hasil inputannya tidak dimasukkan kedalam database hanya ditampilkan saja di halaman website yang sedang diakses. Dalam kasus ini contohnya biasa terjadi pada form pencarian. Sedangkan Stored XSS inputannya dimasukkan kedalam database sekaligus ditampilkan kehalaman website yang sedang diakses. Dalam hal ini contohnya adalah pada form komentar, halaman buku tamu dsb.

Sebagai studi kasus, di sini saya mempunyai halaman komentar sederhana. Berikut kodenya.


<?php  
$conn = mysqli_connect("localhost", "root", "", "blog");
if (isset($_POST["submit"])) {
 $nama = $_POST["nama"];
 $komentar = $_POST["komentar"];
 mysqli_query($conn, "INSERT INTO tbl_komentar (nama,komentar) VALUES('$nama', '$komentar')");
}
$result = mysqli_query($conn, "SELECT * FROM tbl_komentar");
$arr = [];
while ($row = mysqli_fetch_assoc($result)) {
 $arr[] = $row;
}
if (isset($_GET["id"])) {
 $id = $_GET["id"];
 mysqli_query($conn, "DELETE FROM tbl_komentar WHERE id = $id");
 if (mysqli_affected_rows($conn) > 0 || $id) {
  header("Location: index.php");
  exit();
 }
}
?>
<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.7.0/css/font-awesome.min.css">
 <title>Home</title>
 <style>
  *{
   margin: 0;
   padding: 0;
  }
  label{
   display: block;
  }
 </style>
</head>
<body>
 <div style="margin-top: 10px;">
  <?php foreach ($arr as $rows) :?>
  <main style="padding: 10px 0 0 20px;">
   <h3 style="font: inherit;border: 1px solid grey;display: inline-block;margin-bottom: 5px;padding: 2px;">Posted by <b><?= $rows["nama"]; ?></b> on <b><?= date("d-m-Y", strtotime($rows["tanggal"])); ?></b></h3>
   <a style="color: #000;margin: 0 5px;" href="index.php?id=<?= $rows['id']; ?>" onclick="return confirm('yakin?');"><i class="fa fa-close" title="delete"></i></a>
   <div style="width: 40%;border: 1px solid grey;padding: 10px;box-sizing: border-box;">
    <p><?= $rows["komentar"];  ?></p>
   </div>
  </main>
  <?php endforeach; ?>
 </div>
 <div style="margin:40px 0 30px 20px;">
  <form action="" method="post">
   <label for="nama">Nama</label>
   <input type="text" name="nama" id="nama" required="required">
   <label for="komentar">Komentar</label>
   <textarea style="resize: none;" name="komentar" id="komentar" cols="60" rows="10" required="required"></textarea>
   <button style="cursor: pointer;display: block;" type="submit" name="submit">Kirim</button>
  </form>
 </div>
</body>
</html>

Saya mempunyai 4 kolom dalam tabel tbl_komentar yaitu id, nama, tanggal, dan komentar. Namun yang dapat diinputkan langsung oleh user hanya nama dan komentar saja. Pada kode di atas, yang harus diperhatikan adalah kode di bawah ini.


<?php
$conn = mysqli_connect("localhost", "root", "", "blog");
if (isset($_POST["submit"])) {
 $nama = $_POST["nama"];
 $komentar = $_POST["komentar"];

 mysqli_query($conn, "INSERT INTO tbl_komentar (nama,komentar) VALUES('$nama', '$komentar')");
}
$result = mysqli_query($conn, "SELECT * FROM tbl_komentar");
$arr = [];
while ($row = mysqli_fetch_assoc($result)) {
 $arr[] = $row;
}
?>

Kita bisa lihat, ada dua query di atas. Query pertama adalah insert ke database data yang diinputkan oleh user menggunakan metode request POST. Sedangkan query yang kedua adalah untuk menampilkan data yang ada di database pada masing-masing kolom.

Jika ingin mencobanya silahkan save file di atas tadi, lalu buat tabel sesuai kriteria yang sudah dijelaskan. Jika selesai, silahkan jalankan filenya. Coba inputkan script berikut ini pada kolom nama.


<script>alert(1);</script>

Untuk kolom komentar silahkan input terserah. Klik tombol kirim, maka browser kita akan menampilkan sebuah popup box alert yang bertuliskan angka 1. Kenapa hal ini bisa terjadi? Itulah kenapa pada pembahasan di artikel sebelumnya mengenai celah keamanan khususnya yang menggunakan PHP, sangat penting untuk melakukan filtering terlebih dahulu pada setiap metode request baik GET ataupun POST.

Seperti yang kita lihat, tidak ada satupun filter pada metode request POST di atas yang terjadi pada parameter nama dan komentar.


$nama = $_POST["nama"];
$komentar = $_POST["komentar"];

Penyebabnya, user lain dapat dengan bebas menginputkan sesuatu bahkan yang berbahaya sekalipun. Pada contoh di atas, kita berusaha mencoba menginputkan perintah JavaScript berupa alert untuk menampilkan popup. Dengan ini terbukti bahwa segala kode Baik itu HTML ataupun script lain yang diinputkan akan berfungsi sebagaimana mestinya.

Mungkin menggunakan script di atas terlihat tidak terlalu berbahaya. Namun ada beberapa perintah yang sangat berbahaya, di antaranya seperti memasang script yang akan mengubah tampilan website anda (Deface) dan juga membajak cookie pengguna. Lalu bagaimana cara memperbaikinya? Simak ulasan berikut dengan baik.

Bagaimana Cara Memperbaikinya?

Karena yang menjadi berbahaya di sini adalah kode HTML ataupun script yang diinputkan oleh user berfungsi dengan baik, maka yang harus kita lakukan adalah mencegahnya agar menjadi tidak berfungsi. Caranya adalah dengan memfilter metode request POST di atas menggunakan fungsi pada PHP yaitu htmlspecialchars atau strip_tags.

1. Fungsi htmlspecialchars

Dengan menggunakan fungsi ini, semua inputan kode HTML atau script tidak akan berfungsi lagi. Berikut penanganan yang dilakukan oleh fungsi ini.


& (ampersand) menjadi &amp;
" (double quote) menjadi &quot;
' (single quote) menjadi &#039;
< (less than) menjadi &lt;
> (greater than) menjadi &gt;

Jadi jika kita mencoba lagi memasukkan script <script>alert(1);</script> maka akan dirubah menjadi &lt;script&gt;alert(1);&lt;/script&gt;. Dengan begitu kodenya sudah tidak akan berfungsi lagi. Kalian juga bisa lihat perubahannya yang mana sebelum difilter, teks yang tampil kosong namun setelah difilter script yang kita inputkan tercetak sebagai plain text pada websitenya.

Dengan menggunakan fungsi ini, seharusnya kode kita menjadi seperti di bawah ini.


$nama = htmlspecialchars($_POST["nama"]);
$komentar = htmlspecialchars($_POST["komentar"]);

Namun, alangkah lebih baik jika kita gabungkan dengan fungsi mysqli_real_escape_string agar karakter single quote (') bisa dimasukkan kedalam database dengan aman. Sehingga kodenya sekarang seperti ini.


$nama = htmlspecialchars(mysqli_real_escape_string($conn, $_POST["nama"]));
$komentar = htmlspecialchars(mysqli_real_escape_string($conn, $_POST["komentar"]));

2. Fungsi strip_tags

Berbeda dengan fungsi htmlspecialchars, fungsi strip_tags ini tidak merubah kode inputan melainkan menghapusnya langsung. Jadi jika kita menginputkan <script>alert(1);</script> maka outputnya adalah alert(1);. Seperti yang kita lihat, di sini tag <script> dihapus sehingga kodenya tidak berfungsi lagi.

Fungsi ini cocok digunakan untuk bagian komentar. Yang mana pada bagian komentar bisanya memperbolehkan user untuk menginputkan beberapa tag pada HTML seperti <b>, <i>, <a> dsb. Jadi untuk meloloskan beberapa elemen tadi, kita bisa masukkan ke parameter kedua pada fungsi strip_tags ini.

Dengan menerapkan fungsi strip_tags, seharusnya kode kita menjadi seperti di bawah ini.


$nama = htmlspecialchars(mysqli_real_escape_string($conn, $_POST["nama"]));
$komentar = strip_tags(mysqli_real_escape_string($conn, $_POST["komentar"]), "<a><b><i>");

Dengan begitu, sekarang website kita sudah aman dari serangan XSS. Semua inputan sudah dapat terfilter dengan baik. Sehingga tidak perlu khawatir website kita dideface ataupun dicuri cookienya.

About the Author

Seorang yang suka belajar berbagai hal dan membagikannya ke publik agar bisa tumbuh bersama.

Posting Komentar

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.