flawopen.com/ssrf/Php

● CWE-918 · Tinggi
Riset Keamanan · FlawOpen

Server-Side Request Forgery in PHP

How curl_exec in PHP exposes internal networks, and how to filter IPs using FILTER_VALIDATE_IP and CURLOPT_FOLLOWLOCATION.

💡 Penjelasan Sederhana (ELI5)

Bayangkan mengirim kurir kantor untuk mengambil paket di toko umum, tetapi memberinya alamat brankas terkunci di ruang manajer. Karena kurir memiliki lencana akses internal, dia membuka brankas dan menyerahkan rahasia perusahaan kepada Anda.

Konsep Kunci & Istilah

Web Application Security
Komponen arsitektur utama yang terpengaruh oleh CWE-918.
CWE-918
Klasifikasi standar Common Weakness Enumeration (CWE) untuk ssrf-php.
Defense-in-Depth
Verifikasi rekayasa berlapis dan isolasi batas waktu proses (runtime).

Alur Serangan Langkah demi Langkah

Step 1

Penerimaan URL Jarak Jauh Tidak Tepercaya

Aplikasi menerima parameter URL dari pengguna untuk mengunduh avatar, webhook, atau pratinjau dokumen.

Step 2

Pengalamatan Jaringan Internal

Penyerang memasukkan alamat loopback atau layanan metadata cloud (misal: http://169.254.169.254/latest/meta-data/).

Step 3

Koneksi Keluar Soket Tanpa Filter

Klien HTTP server mengirim permintaan dari dalam VPC privat tanpa memeriksa rentang subnet privat.

Step 4

Pencurian Kredensial Cloud IAM

Layanan metadata internal mempercayai permintaan dan mengembalikan token kredensial IAM sementara ke penyerang.

Kode Sumber: Rentan vs Aman

✕ IMPLEMENTASI RENTAN
<?php
// VULNERABLE: file_get_contents on user-controlled URL
$url = $_GET['url'];

// Attacker input: http://169.254.169.254/latest/meta-data/
$content = file_get_contents($url);

echo $content;
?>
✓ PERBAIKAN AMAN & KUAT
<?php
// HARDENED: Parse URL, resolve DNS, filter private IPs, and disable redirects
$url = $_GET['url'] ?? '';

$parsed = parse_url($url);
if (!$parsed || !in_array(strtolower($parsed['scheme'] ?? ''), ['http', 'https'], true)) {
    http_response_code(400);
    exit('Invalid URL scheme');
}

$host = $parsed['host'] ?? '';
$ips = gethostbynamel($host);

if (!$ips) {
    http_response_code(400);
    exit('Unable to resolve host');
}

// Check every resolved IP address
foreach ($ips as $ip) {
    if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
        http_response_code(403);
        exit('Access to private/internal address denied');
    }
}

// Fetch using cURL with redirects disabled
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false, // Prevent redirect bypasses
    CURLOPT_TIMEOUT        => 3,
    CURLOPT_PROTOCOLS      => CURLPROTO_HTTP | CURLPROTO_HTTPS,
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>

Daftar Periksa Penguatan Sistem Rekayasa

References