Frontend Security 101: Clickjacking

Halo teman-teman semua, terima kasih sudah cukup sabar menunggu saya posting blog ya setelah sebulan terakhir cukup tidak konsisten karena satu dan lain hal. Sebenernya beberapa waktu yang lalu saya udah sempet buka “quiz” di instagram untuk minta urun saran topik di blog ini, tapi sarannya kok berad-berad eh, saya kayaknya perlu riset lebih lanjut dulu kalo gitu mah. Maka dari itu di post kali ini saya pengen ngelanjutin seri Frontend Security 101 yang sudah agak lama tidak diupdate, teruntuk teman-teman yang kemarin ngasih topik, sabar ya gaes, insyaAllaah akan saya bahas kok 😉.

Oke tanpa berlama-lama, let’s dive into the topic!

Kalau frontend developer mungkin ketika ditanya terkait potential security issues di frontend apa aja sudah familiar dengan CSRF/XSS lah ya, atau at least pernah denger. Tapi mungkin belum terlalu familiar dengan yang namanya clickjacking—opo meneh kui clickjacking pak?—meskipun mungkin sebenernya di real case kita udah sering menemui. Clickjacking adalah teknik hekel mengelabui user untuk meng-klik elemen yang terlihat aman padahal berbahaya.

WSTG - v4.1 | OWASP Foundation

Contohnya misal kita sedang ada di sebuah laman dan ada tombol “Klaim hadiah”, tapi ternyata ada tombol lain yang tidak terlihat, sehingga ketika kamu mengklik tombol “Klaim hadiah”, secara tidak kamu ketahui ternyata kamu juga ikut mengklik hidden button tersebut. Yang mungkin melakukan operasi aneh, melakukan pembelian, atau mengirim pesan ke seseorang.

Nah kalo gitu harusnya ini bukan ranahnya frontend tapi user in general dong?! Itu betul, tapi… sebagai frontend mungkin aja aplikasi kita dipake sebagai “topeng” untuk menutupi hidden button tadi, that’s what this article talking about, bruh.

Terus gimana cara kita menangani agar aplikasi yang kita buat tidak dipakai untuk modus operandi ini? Sebenernya ini sudah terjawab di post seri yang sebelumnya, yaitu dengan memanfaatkan Content Security Policy (CSP) dan X-Frame-Options header.

CSP kita sudah bahas sebelumnya, sedangkan X-Frame-Options belum. Singkatnya X-Frame-Options adalah request header yang memungkinkan kita bisa mengontrol apakah aplikasi kita dapat diembed dalam iframe atau tidak.

Misal kita punya aplikasi React yang berjalan di server yang kita kendalikan (seperti Express.js), kita bisa menambahkan header HTTP X-Frame-Options di respon server untuk mencegah aplikasi di-embed di dalam iframe situs lain. Ini bisa dilakukan seperti ini:

// Pada server Express.js kita
const express = require('express');
const app = express();

// Tambahkan header untuk mencegah clickjacking
app.use((req, res, next) => {
  res.setHeader('X-Frame-Options', 'DENY'); // Pilihan lain: 'SAMEORIGIN' jika ingin iframe hanya dari domain yang sama
  next();
});

app.get('/', (req, res) => {
  res.send('Hello, ini adalah aplikasi React.js yang aman!');
});

app.listen(3000, () => {
  console.log('Server berjalan di http://localhost:3000');
});
  • DENY: Menghindari situs ditampilkan dalam iframe sama sekali.

  • SAMEORIGIN: Mengizinkan aplikasi di-embed hanya di iframe dari domain yang sama.

Dengan menambahkan header X-Frame-Options, browser akan menolak untuk menampilkan aplikasi kita dalam iframe pada situs lain, sehingga membantu mencegah clickjacking.

Sedangkan untuk bagian implementasi CSP, kita bisa menambahkan header CSP yang mengatur iframe hanya bisa di-load dari domain yang sama atau dari domain yang kita tentukan. Contohnya di express js

app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', "frame-ancestors 'self'"); // Hanya mengizinkan iframe dari domain yang sama
  next();
});

frame-ancestors 'self': Mengizinkan hanya domain sendiri untuk menampilkan halaman di dalam iframe.

Ah ash tapi aku enggak pake React di dalem express gimana dong?

Kalo kita pake React aja, kita juga bisa sebenernya melakukan pengecekan apakah aplikasi kita ini diload di dalem iframe, kalo iya, kita bisa block dan render null atau dummy dengan memanfaatkan property window.self dan window.top, misalnya:

import React, { useEffect } from 'react';

function App() {
  useEffect(() => {
    // Cek apakah aplikasi ini dibuka dalam iframe
    if (window.self !== window.top) {
      // Jika iya, cegah aplikasi untuk ditampilkan
      document.body.innerHTML = '<h1>Clickjacking protection: Access Denied</h1>';
    }
  }, []);

  return (
    <div className="App">
      <h1>Aplikasi React.js Aman dari Clickjacking</h1>
      {/* Konten aplikasi */}
    </div>
  );
}

export default App;

Pada contoh di atas, kita cek apakah window.self sama dengan window.top. Jika tidak sama, berarti aplikasi sedang di-load di dalam iframe. Dalam kasus ini, kita bisa memutuskan untuk menampilkan pesan khusus atau mencegah akses ke aplikasi.

Kesimpulannya dengan mengaplikasikan X-Frame-Options, CSP, maupun pengecekan melalui window property di aplikasi React kita bisa mencegah dari serangan clickjacking, sehingga membantu memberikan rasa aman kepada pengguna kita. Karena dengan begitu kita bisa memastikan aplikasi kita tidak bisa diiframe dan disalahgunakan oleh pihak tidak bertanggung jawab.

I think that’s pretty much for the post today, see you on the next post and have a great day!

0
Subscribe to my newsletter

Read articles from Ashari Muhammad Hisbulloh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ashari Muhammad Hisbulloh
Ashari Muhammad Hisbulloh