Unrestricted File Upload — OWASP (Bahasa Indonesia)

Naufal Ardhani
4 min readMar 12, 2023

Unrestricted File Upload adalah sebuah kerentanan keamanan di aplikasi web yang memungkinkan pengguna untuk mengunggah file tanpa adanya validasi dan filtering yang memadai.

Impact / Dampak

Hal ini dapat memungkinkan penyerang untuk mengunggah file berbahaya seperti script, shellcode, atau malware ke server aplikasi web yang rentan, dan dapat digunakan untuk melakukan serangan seperti:

  1. Injeksi kode: Penyerang dapat mengunggah file yang berisi kode berbahaya, yang dapat dieksekusi pada server dan mengambil alih kendali sistem.
  2. Serangan XSS: Penyerang dapat mengunggah file yang berisi payload XSS, yang dapat disisipkan ke dalam halaman web dan dieksekusi oleh pengguna yang tidak curiga.
  3. Pelanggaran data sensitif: Penyerang dapat mengunggah file yang mengandung informasi sensitif seperti informasi pribadi atau informasi login, yang dapat digunakan untuk melakukan serangan lain seperti pencurian identitas atau pengambilalihan akun.

Mitigasi / Antisipasi

Untuk menghindari kerentanan Unrestricted File Upload, aplikasi web harus menerapkan validasi dan filtering yang memadai pada file yang diunggah oleh pengguna. Hal ini meliputi:

  1. Memeriksa tipe file: Aplikasi harus memverifikasi bahwa file yang diunggah adalah tipe file yang diizinkan, dan menolak file yang tidak diizinkan.
  2. Memeriksa ukuran file: Aplikasi harus membatasi ukuran file yang diunggah oleh pengguna, untuk mencegah pengunggahan file yang terlalu besar yang dapat membebani sistem.
  3. Memeriksa isi file: Aplikasi harus memeriksa isi file untuk memastikan bahwa tidak ada payload berbahaya seperti script atau shellcode yang disisipkan.

Vulnerable Code

Berikut contoh kode PHP yang rentan terhadap Unrestricted File Upload:

<?php
if(isset($_POST['submit'])) {
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "File is not an image.";
$uploadOk = 0;
}
}

// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}

// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}

// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
}
?>

Pada kode di atas, terdapat validasi untuk tipe file dan ukuran file yang diunggah. Namun, tidak ada validasi untuk isi file dan tidak ada filtering untuk memastikan bahwa file yang diunggah adalah file gambar yang valid. Oleh karena itu, kode di atas rentan terhadap Unrestricted File Upload, dan dapat digunakan oleh penyerang untuk mengunggah file berbahaya ke server.

Secure Code

Berikut adalah contoh kode PHP yang sudah tidak rentan terhadap Unrestricted File Upload:

<?php
if(isset($_POST['submit'])) {
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// Check if image file is a actual image or fake image
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check === false) {
echo "File is not an image.";
$uploadOk = 0;
}

// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}

// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}

// Generate a random file name to prevent file overwrite
$random_name = md5(uniqid(rand(), true)) . "." . $imageFileType;
$target_file = $target_dir . $random_name;

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
}
?>

Pada kode di atas, validasi tipe file dan ukuran file tetap dilakukan, namun validasi isi file dan filtering tipe file yang diizinkan diperbarui. Di sini, kami menggunakan fungsi getimagesize() untuk memeriksa apakah file yang diunggah adalah gambar atau bukan. Kami juga menggunakan fungsi md5() untuk menghasilkan nama file yang acak dan unik, sehingga menghindari kemungkinan overwrite file yang sudah ada.

Dengan menerapkan perubahan-perubahan tersebut, kode PHP di atas menjadi lebih aman terhadap serangan Unrestricted File Upload.

--

--