CODEBOOK
Website Platform Belajar Dan Edukasi
By Shadownex 2025-2026
← Kembali ke Katalog Lab
SSRFUNSOLVEDReward: +150 XP

Lab 11: Server-Side Request Forgery (SSRF) accessing cloud instance metadata

Utilitas pengujian Webhook melakukan HTTP GET request ke URL eksternal apapun yang dimasukkan pengguna tanpa memfilter alamat IP lokal atau privat.

TARGET OBJECTIVE & BRIEFING

Objective:

Paksa server untuk melakukan HTTP request ke endpoint metadata internal Cloud `http://169.254.169.254/latest/meta-data/` untuk membocorkan IAM Secret Credentials.

Aplikasi developer WebhookTester menyediakan fitur penguji endpoint HTTP callback. Pengguna memasukkan URL dan server backend akan mengeksekusi `axios.get(userUrl)`. Karena server berada di jaringan internal cloud (AWS/GCP), alamat IP reserved `169.254.169.254` dapat diakses oleh server untuk membaca token rahasia IAM Role.

PENTESTING METHODOLOGY
1. Buka utilitas penguji Webhook di browser.
2. Masukkan URL privat Cloud Metadata: `http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-role`.
3. Klik "Tes Webhook" dan amati respon yang dikembalikan oleh backend.
4. Temukan kredensial rahasia AWS Secret Access Key & Flag di respon JSON.
CODE SECURITY INSPECTION

SSRF mengeksploitasi kepercayaan server pada jaringan internal. CodeBook menerapkan filter anti-private IP dan DNS resolution check sebelum melakukan HTTP request.

VULNERABLE CODE

// KODE RENTAN (Unrestricted HTTP Fetch)
app.post('/api/webhook/test', async (req, res) => {
  const { url } = req.body;
  try {
    // DANGEROUS: Server melakukan HTTP GET ke URL apapun pilihan user!
    const response = await axios.get(url);
    res.json({ statusCode: response.status, body: response.data });
  } catch (err) {
    res.status(500).send('Webhook failed');
  }
});

SECURE CODEBOOK IMPLEMENTATION

// KODE AMAN CODEBOOK STANDARD (Domain Whitelist & Private IP Blocking)
app.post('/api/webhook/test', async (req, res) => {
  const { url } = req.body;
  const parsed = new URL(url);
  
  // SAFE 1: Hanya izinkan protokol HTTP/HTTPS
  if (!['http:', 'https:'].includes(parsed.protocol)) return res.status(400).send('Invalid Protocol');
  
  // SAFE 2: Blokir IP Privat / Loopback / Metadata (127.0.0.1, 169.254.169.254, 10.0.0.0/8, etc)
  if (isPrivateOrLocalIP(parsed.hostname)) {
    return res.status(403).send('Akses ke alamat IP internal dilarang!');
  }
  
  const response = await axios.get(url);
  res.json({ statusCode: response.status, body: response.data });
});