Home / Artikel / Web Security
Web Security

Redirect URL Bukan Sekadar Fitur: Cara Mencegah Website Dipakai Mengantar Korban ke Phishing

Fitur redirect setelah login, logout, atau pembayaran terlihat sederhana, tetapi bisa menjadi pintu masuk phishing jika URL tujuan diterima mentah dari pengguna. Berikut cara mengenali risikonya dan membuat redirect leb…

Redirect URL Bukan Sekadar Fitur: Cara Mencegah Website Dipakai Mengantar Korban ke Phishing

Fitur redirect sering dianggap bagian kecil dari website: pengguna selesai login lalu diarahkan ke dashboard, atau setelah pembayaran dikembalikan ke halaman konfirmasi. Masalahnya muncul ketika alamat tujuan diambil langsung dari parameter URL tanpa pemeriksaan yang cukup.

Dalam kondisi seperti itu, website Anda bisa dipakai untuk mengantar orang ke situs phishing. Tautannya tetap memakai domain yang terlihat tepercaya, tetapi setelah diklik pengguna dibawa ke alamat lain yang dikendalikan penyerang. Ini bukan sekadar masalah tampilan. Nama baik domain, email notifikasi, dan alur login bisa ikut disalahgunakan.

Apa yang dimaksud dengan open redirect?

Open redirect adalah kondisi ketika website menerima alamat tujuan dari pengguna lalu melakukan pengalihan tanpa memastikan bahwa alamat tersebut aman. Contoh sederhananya:

https://contoh.com/redirect?url=https://situs-lain.com

Jika endpoint tersebut menerima nilai url apa adanya, siapa pun dapat mengganti alamatnya menjadi situs berbahaya. Tautan seperti ini lebih meyakinkan dibanding tautan phishing biasa karena bagian awalnya masih memakai domain resmi.

Risikonya tidak selalu berupa pencurian password secara langsung. Open redirect dapat dipakai untuk membuat kampanye phishing terlihat lebih kredibel, menyamarkan tujuan tautan pada email, atau mengarahkan pengguna ke halaman berisi malware dan penipuan.

Kenapa redirect sering dibuat terlalu longgar?

Penyebabnya biasanya bukan karena developer sengaja mengabaikan keamanan. Redirect dibangun untuk memenuhi kebutuhan yang masuk akal: kembali ke halaman sebelum login, mengarahkan pengguna ke halaman yang dipilih, atau menyimpan tujuan ketika proses pembayaran belum selesai.

Masalahnya, kebutuhan tersebut sering diterjemahkan menjadi kode singkat seperti ini:

$url = $_GET['url'] ?? '/';
header('Location: ' . $url);
exit;

Kode tersebut hanya memindahkan tanggung jawab kepada input pengguna. Browser akan mengikuti alamat yang diberikan selama formatnya terlihat valid, termasuk alamat eksternal yang tidak pernah direncanakan oleh pemilik website.

Pola yang lebih aman: gunakan tujuan internal

Pilihan paling aman adalah tidak menerima URL lengkap dari pengguna. Simpan hanya nama tujuan yang sudah dikenal aplikasi, lalu petakan nama tersebut ke alamat internal.

$destinations = [
    'dashboard' => '/dashboard',
    'orders'    => '/pesanan',
    'profile'   => '/profil'
];

$key = $_GET['to'] ?? 'dashboard';
$url = $destinations[$key] ?? '/';

header('Location: ' . $url, true, 302);
exit;

Dengan pola ini, pengguna tidak bisa mengubah tujuan menjadi domain asing. Jika kebutuhan aplikasi berubah, daftar tujuan dapat ditinjau dan diuji sebagai bagian dari kode, bukan dibiarkan terbuka melalui parameter URL.

Jika harus menerima URL, batasi dengan ketat

Ada kasus ketika aplikasi memang perlu mengarahkan pengguna ke alamat eksternal, misalnya setelah proses pembayaran atau ketika menghubungkan layanan pihak ketiga. Dalam situasi tersebut, jangan hanya memeriksa apakah URL diawali dengan https://. Pemeriksaan harus mencakup host, skema, dan format URL.

Contoh pendekatan di PHP adalah membuat daftar domain yang memang diizinkan:

$allowedHosts = [
    'partner.example.com',
    'payment.example.net'
];

$target = $_GET['url'] ?? '/';
$parts = parse_url($target);

$isAllowed = isset($parts['scheme'], $parts['host'])
    && $parts['scheme'] === 'https'
    && in_array(strtolower($parts['host']), $allowedHosts, true);

if (!$isAllowed) {
    $target = '/';
}

header('Location: ' . $target, true, 302);
exit;

Validasi seperti ini tetap perlu disesuaikan dengan arsitektur aplikasi. Perhatikan juga variasi hostname, port, subdomain, dan kemungkinan penggunaan URL dengan format yang membingungkan. Jika daftar domain yang diizinkan bisa dibuat lebih kecil, pilih daftar yang lebih kecil.

Perhatikan redirect setelah login

Parameter seperti next, return, atau redirect_to sering muncul dalam alur autentikasi. Fungsinya berguna, tetapi menjadi berbahaya jika nilai tersebut dapat diisi dengan URL eksternal.

Untuk halaman login, pendekatan yang sederhana adalah hanya menerima path lokal, bukan URL lengkap:

$next = $_GET['next'] ?? '/dashboard';

if (
    $next === '' ||
    $next[0] !== '/' ||
    str_starts_with($next, '//')
) {
    $next = '/dashboard';
}

Pengecekan // penting karena beberapa browser dapat menafsirkan nilai seperti //penipu.example sebagai alamat eksternal. Jangan lupa bahwa validasi harus dilakukan di server. Pemeriksaan di JavaScript hanya membantu pengalaman pengguna, bukan menjadi lapisan keamanan utama.

Bagaimana dengan WordPress?

Di WordPress, risiko redirect dapat muncul dari plugin, tema, atau kode kustom yang memproses parameter URL. Hindari mengirimkan nilai pengguna langsung ke fungsi pengalihan.

Gunakan fungsi validasi bawaan WordPress ketika sesuai dengan kebutuhan:

$redirect = isset($_GET['redirect_to'])
    ? wp_unslash($_GET['redirect_to'])
    : home_url('/');

$redirect = wp_validate_redirect(
    $redirect,
    home_url('/')
);

wp_safe_redirect($redirect);
exit;

wp_validate_redirect() membantu memastikan tujuan pengalihan tidak keluar dari daftar host yang diperbolehkan WordPress. wp_safe_redirect() juga dirancang untuk pengalihan yang lebih aman. Namun, fungsi tersebut bukan alasan untuk menerima semua input tanpa memahami alur plugin atau kebutuhan bisnisnya.

Apa artinya bagi kita?

Open redirect sering tidak terlihat dalam pemindaian sederhana karena website tetap berjalan normal. Tidak ada halaman rusak, tidak ada pesan error, dan pengguna yang sah tetap bisa login. Dampaknya baru terasa ketika tautan tersebut dipakai dalam kampanye penipuan.

Karena itu, pengujian keamanan sebaiknya tidak hanya memeriksa apakah redirect bekerja, tetapi juga apakah redirect menolak tujuan yang tidak semestinya.

Yang bisa dilakukan sekarang

  • Cari parameter dengan nama seperti url, next, return, redirect, atau redirect_to.
  • Periksa apakah nilainya langsung dikirim ke header Location atau fungsi redirect.
  • Ganti URL bebas dengan daftar tujuan internal jika memungkinkan.
  • Jika tujuan eksternal wajib didukung, gunakan allowlist domain yang sempit.
  • Tolak skema selain HTTPS untuk layanan eksternal.
  • Uji nilai seperti https://example.org, //example.org, URL dengan username, dan hostname yang mirip.
  • Tinjau kembali plugin atau library yang menangani login, pembayaran, dan integrasi pihak ketiga.

Redirect memang fitur kecil, tetapi ia berada di titik yang sering dilewati pengguna. Dengan membatasi tujuan dan memvalidasi input di server, website tidak hanya menjadi lebih aman secara teknis, tetapi juga lebih sulit dipakai untuk membangun kepercayaan palsu.

Jelajahi juga

– Rio Yotto @rioyotto