Insecure file upload merupakan salah satu masalah keamanan yang perlu diperhatikan pada aplikasi web yang menyediakan fitur unggah dokumen. Masalah ini dapat terjadi ketika aplikasi tidak melakukan validasi yang memadai terhadap tipe, nama, ukuran, isi, maupun lokasi penyimpanan file.
Namun, fitur yang terlihat sederhana ini dapat menjadi masalah keamanan apabila aplikasi tidak melakukan validasi dengan baik. Server harus menentukan file apa yang boleh diterima, bagaimana file tersebut disimpan, dan bagaimana file tersebut diberikan kembali kepada pengguna.
Salah satu hal yang sering menjadi pertanyaan adalah mengapa file .php yang berhasil diunggah pada aplikasi berbasis Node.js tidak otomatis dapat dieksekusi.
Jawabannya berkaitan dengan bagaimana Node.js menangani file dan bagaimana server dikonfigurasi.
Artikel ini membahas konsep insecure file upload, alasan file .php tidak otomatis dieksekusi pada stack Node.js, risiko ketika file upload dapat diakses melalui browser, serta beberapa prinsip dasar untuk mengamankan fitur upload.
📘 Apa yang Akan Dipelajari?
Pada artikel ini kita akan membahas beberapa hal berikut:
- Mengenal insecure file upload.
- Memahami hubungan file upload dengan CWE-434.
- Memahami mengapa file
.phptidak otomatis dieksekusi oleh Node.js. - Mengenal pentingnya validasi tipe dan isi file.
- Memahami risiko penyimpanan file pada webroot.
- Mengenal risiko ketika file upload dapat dirender oleh browser.
- Memahami pentingnya nama file yang dibuat oleh server.
- Mengenal beberapa prinsip dasar pengamanan file upload pada Node.js dan Express.
- Menyusun analisis keamanan file upload secara sistematis.
💡 Mengapa File Upload Perlu Diperhatikan?
File upload merupakan input yang berasal dari pengguna.
Artinya, aplikasi tidak dapat begitu saja mempercayai nama file, ekstensi, ukuran, maupun informasi tipe file yang dikirimkan oleh pengguna.
Secara sederhana, proses upload dapat digambarkan seperti berikut:
Pengguna
↓
Upload File
↓
Server
↓
Validasi
↓
Penyimpanan
↓
File dapat digunakan kembali
Masalah dapat muncul apabila salah satu tahap tersebut tidak memiliki kontrol yang sesuai.
Misalnya, aplikasi hanya memeriksa ekstensi file dan langsung menyimpannya ke folder publik.
Dalam kondisi tersebut, aplikasi mungkin tidak memiliki kontrol yang cukup terhadap file yang akhirnya tersedia melalui web.
Karena itu, keamanan file upload tidak hanya berkaitan dengan pertanyaan apakah sebuah file dapat dieksekusi oleh server.
Kita juga perlu melihat bagaimana file disimpan dan bagaimana file tersebut diberikan kembali kepada browser.
🎯 Apa Itu Insecure File Upload?
Insecure file upload adalah kondisi ketika aplikasi menerima file dari pengguna tanpa pembatasan atau validasi yang memadai.
Masalah ini dapat berkaitan dengan jenis file, ukuran, nama file, isi file, lokasi penyimpanan, maupun cara file tersebut disajikan.
Salah satu klasifikasi yang berkaitan dengan masalah ini adalah CWE-434, yaitu Unrestricted Upload of File with Dangerous Type.
Secara umum, proses upload terdiri dari beberapa tahap:
- Pengguna memilih file.
- Browser mengirim file ke server.
- Server menerima file.
- Server melakukan validasi.
- Server menentukan nama dan lokasi penyimpanan.
- File disimpan.
- File dapat diberikan kembali kepada pengguna jika diperlukan.
Setiap tahap tersebut perlu dipertimbangkan dari sisi keamanan.

Antarmuka fitur upload dokumen pada aplikasi lab.
Dari antarmuka tersebut terlihat bahwa aplikasi menyediakan fitur untuk menerima file dari pengguna. Pada tahap berikutnya, yang perlu diperhatikan bukan hanya apakah file berhasil diunggah, tetapi bagaimana server memvalidasi dan menyimpannya.
🧠 Mengapa File .php Tidak Berhasil Dieksekusi di Node.js?
Ini merupakan konsep penting ketika menganalisis aplikasi berbasis Node.js.
Node.js dan PHP menggunakan runtime yang berbeda.
File .php dapat diproses apabila terdapat PHP interpreter dan konfigurasi server yang memang menangani file PHP.
Sementara itu, aplikasi Node.js tidak otomatis menggunakan PHP interpreter untuk memproses file .php.
Contohnya, ketika sebuah aplikasi Node.js menerima file:
file.php
↓
Node.js menerima file
↓
File disimpan
↓
Tidak ada PHP interpreter
↓
File PHP tidak otomatis dieksekusi
Dengan demikian, keberhasilan upload file .php tidak sama dengan keberhasilan menjalankan kode PHP.
File tersebut bisa saja hanya menjadi file biasa yang tersimpan di filesystem.
Namun, kondisi tersebut juga tidak berarti fitur upload sudah aman.
Masih terdapat pertanyaan lain yang perlu diperiksa, misalnya:
- Di mana file disimpan?
- Apakah file dapat diakses secara langsung?
- Apakah file dapat dirender oleh browser?
- Apakah aplikasi memiliki validasi tipe file?
- Apakah ukuran file dibatasi?
- Apakah nama file dikontrol oleh server?
Pertanyaan tersebut membantu kita memahami risiko sebenarnya.
📂 Mengapa Lokasi Penyimpanan Penting?
Salah satu hal yang perlu diperhatikan adalah lokasi penyimpanan file.
Misalnya sebuah aplikasi memiliki struktur:
project/
├── public/
│ ├── index.html
│ └── uploads/
│ ├── gambar.png
│ └── dokumen.pdf
└── server.js
Folder public biasanya digunakan untuk resource yang dapat diakses melalui web.
Jika file upload ditempatkan di dalam folder tersebut, file berpotensi dapat diakses secara langsung melalui URL.
Contohnya:
https://example.com/uploads/dokumen.pdfHal ini mungkin memang dibutuhkan untuk gambar atau resource publik.
Namun, untuk file yang bersifat pribadi, menyimpannya sebagai resource publik bukan pilihan yang ideal.
Karena itu, file upload yang bersifat private sebaiknya disimpan pada lokasi yang tidak langsung dipublikasikan oleh web server.
🔎 Mengapa Validasi Ekstensi Saja Tidak Cukup?
Salah satu pendekatan sederhana adalah memeriksa ekstensi file.
Misalnya:
.pdf
.jpg
.pngAplikasi kemudian hanya menerima ekstensi yang sudah ditentukan.
Pendekatan ini lebih baik daripada menerima semua jenis file, tetapi ekstensi saja tidak selalu cukup untuk menentukan karakteristik sebenarnya dari sebuah file.
Informasi lain seperti MIME type dan isi file juga dapat dipertimbangkan.
Konsep validasinya dapat digambarkan:
Nama File
↓
Periksa Ekstensi
↓
Periksa Tipe
↓
Periksa Isi Jika Diperlukan
↓
Periksa Ukuran
↓
Terima / Tolak
Validasi tersebut harus dilakukan di sisi server karena browser tidak dapat dijadikan sebagai satu-satunya lapisan keamanan.

Hasil pengujian validasi tipe file pada lingkungan lab.
Pengujian tersebut memperlihatkan bahwa informasi tipe file yang dikirim oleh client perlu dibedakan dari keputusan akhir server. Server tetap perlu menentukan sendiri apakah file tersebut sesuai dengan aturan aplikasi.
Pada hasil pengujian, file dengan ekstensi tertentu tetap disajikan oleh server menggunakan tipe yang berbeda. Hal ini menjadi contoh bahwa deklarasi tipe dari client tidak seharusnya menjadi satu-satunya dasar keputusan keamanan.
📏 Membatasi Ukuran File
Ukuran file juga merupakan bagian dari keamanan upload.
Tanpa pembatasan ukuran, pengguna dapat mengirim file yang sangat besar dan menggunakan resource server secara berlebihan.
Contoh konfigurasi sederhana menggunakan middleware upload:
const upload = multer({
limits: {
fileSize: 5 * 1024 * 1024
}
});
Pada contoh tersebut, ukuran maksimum ditetapkan sebesar 5 MB.
Nilai sebenarnya perlu disesuaikan dengan kebutuhan aplikasi.
Aplikasi untuk mengunggah dokumen laporan mungkin membutuhkan batas yang berbeda dengan aplikasi yang digunakan untuk mengunggah gambar.
🏷️ Mengapa Nama File Perlu Dibuat oleh Server?
Nama file yang berasal dari pengguna sebaiknya tidak langsung digunakan sebagai nama file internal pada server.
Misalnya pengguna mengunggah:
laporan-keuangan.pdf
Server dapat membuat identifier baru seperti:
a83f91c2e7b44f12.pdf
Pendekatan ini memberikan beberapa keuntungan:
- Mengurangi kemungkinan konflik nama.
- Mengurangi ketergantungan pada input nama file.
- Memudahkan pengelolaan file.
- Membuat identifier file lebih konsisten.
Dalam aplikasi yang lebih kompleks, metadata seperti nama asli file dapat disimpan secara terpisah di database.

Hasil pengujian validasi nama file pada lingkungan lab.
Berdasarkan hasil pengujian, aplikasi melakukan normalisasi terhadap nama file sehingga nama yang digunakan untuk penyimpanan tetap berada di direktori upload.
Hasil ini menunjukkan bahwa validasi dan normalisasi path merupakan bagian penting dalam proses penyimpanan file.
🌐 Risiko Ketika File Dapat Dirender Browser
Keamanan file upload tidak hanya berkaitan dengan server.
Browser juga perlu diperhatikan.
Mau Kuasai Insecure File Upload: Kenapa File .php Tidak Berhasil di Stack Node.js Sampai Bisa Praktik Langsung?
Materi ini juga kami ajarkan langsung di kelas Edusoft Center, dibimbing mentor, sampai kamu bisa praktik nyata — bukan cuma baca teori.
Tanya Kursus via WhatsApp Lihat contoh project nyata dari siswa kami →
File yang diunggah dapat menjadi masalah apabila aplikasi menyajikannya kembali dengan cara yang membuat browser memperlakukannya sebagai konten aktif.
Salah satu konsep yang berkaitan dengan kondisi tersebut adalah stored XSS.
Secara konseptual:
File diterima
↓
File disimpan
↓
File dapat diakses melalui aplikasi
↓
Browser menerima file
↓
Browser menafsirkan konten
↓
Risiko keamanan dapat muncul
Karena itu, aplikasi harus menentukan dengan jelas apakah file hanya boleh diunduh atau memang perlu ditampilkan langsung di browser.
Untuk dokumen tertentu, menyajikannya sebagai attachment dapat menjadi pilihan yang lebih sesuai.

Tampilan browser pada lingkungan lab ketika file upload diperlakukan sebagai konten HTML.
Screenshot tersebut menunjukkan dampak ketika file yang diunggah dapat disajikan kembali sebagai konten HTML pada origin aplikasi.
Temuan ini memperlihatkan bahwa risiko file upload tidak hanya berkaitan dengan eksekusi di sisi server, tetapi juga bagaimana browser memperlakukan file tersebut.

Caption: Bukti pengujian pada lingkungan lab yang menunjukkan proses penerimaan dan penyajian file HTML.
Hasil tersebut menjadi bukti teknis yang mendukung temuan pada browser. Aplikasi menerima file HTML dan kemudian menyediakan file tersebut melalui endpoint upload.
Kondisi seperti ini perlu diperhatikan apabila file upload tidak seharusnya diperlakukan sebagai konten HTML aktif.
📥 Menyajikan File sebagai Download
Aplikasi dapat menyediakan endpoint khusus untuk mengunduh file.
Contoh sederhananya:
app.get('/download/:name', async (req, res) => {
// Periksa autentikasi
// Periksa authorization
// Cari file berdasarkan identifier
// Pastikan lokasi file valid
// Kirim file sebagai attachment
});
Pada implementasi nyata, endpoint tersebut perlu memastikan bahwa pengguna memang memiliki hak untuk mengakses file.
Jangan hanya mencari file berdasarkan input mentah dari URL.
Alur yang lebih aman dapat dibuat seperti:
Request Download
↓
Cek Login
↓
Cek Hak Akses
↓
Cari Identifier File
↓
Validasi Lokasi File
↓
Kirim File
🛡️ Prinsip Dasar Pengamanan File Upload
Ada beberapa prinsip yang dapat digunakan ketika membangun fitur upload.
1. Gunakan Allowlist
Tentukan tipe file yang memang diperlukan oleh aplikasi.
Contohnya:
PDF
JPG
PNGJika aplikasi tidak membutuhkan file lain, tidak perlu menerimanya.
2. Validasi di Server
Validasi pada browser hanya membantu pengalaman pengguna.
Keputusan keamanan tetap harus dilakukan di server.
3. Batasi Ukuran File
Tentukan ukuran maksimum sesuai kebutuhan aplikasi.
4. Gunakan Nama File yang Dibuat Server
Jangan menggunakan nama asli file sebagai satu-satunya identifier internal.
5. Gunakan Private Storage untuk File Private
File yang bersifat pribadi sebaiknya tidak disimpan sebagai resource publik.
6. Kontrol Akses File
Pengguna yang sudah login belum tentu boleh mengakses seluruh file.
Pastikan aplikasi melakukan authorization.
7. Tentukan Bagaimana File Disajikan
Jika file hanya perlu diunduh, jangan menjadikannya konten web aktif tanpa alasan.

Caption: Perbandingan implementasi sebelum dan sesudah penerapan kontrol keamanan pada fitur upload.
Implementasi setelah perbaikan menambahkan beberapa lapisan validasi, termasuk pembatasan tipe file, pemeriksaan ukuran, pembuatan nama file, serta pengaturan penyimpanan.
Pendekatan ini menunjukkan bahwa keamanan upload tidak bergantung pada satu pemeriksaan saja.
🧩 Studi Kasus Sederhana
Misalnya sebuah aplikasi internal memiliki fitur upload dokumen.
Kebutuhannya adalah:
Jenis File:
PDF, JPG, PNG
Ukuran Maksimum:
5 MB
Pengguna:
Pengguna yang sudah login
Penyimpanan:
Private Storage
Berdasarkan kebutuhan tersebut, proses upload dapat dirancang:
Upload
↓
Cek Authentication
↓
Cek Ukuran
↓
Cek Ekstensi
↓
Cek Tipe / Isi File
↓
Buat Nama File Baru
↓
Simpan di Private Storage
↓
Simpan Metadata
Ketika pengguna ingin mengunduh:
Request Download
↓
Cek Authentication
↓
Cek Authorization
↓
Cari File
↓
Validasi Path
↓
Kirim File
Dengan alur tersebut, keamanan tidak hanya bergantung pada satu pemeriksaan.
⚠️ Kesalahan yang Sering Dilakukan
Hanya Memblokir File .php
Memblokir satu ekstensi tidak otomatis menyelesaikan seluruh masalah file upload.
Aplikasi tetap perlu memiliki aturan tipe file yang jelas.
Hanya Mempercayai Content-Type
Content-Type dari request tidak sebaiknya menjadi satu-satunya dasar validasi.
Gunakan pemeriksaan tambahan yang sesuai dengan jenis file.
Menyimpan Semua File di Folder Publik
Tidak semua file perlu menjadi resource publik.
Pisahkan file private dari resource aplikasi yang memang harus dapat diakses publik.
Menggunakan Nama File dari Pengguna
Nama file pengguna sebaiknya tidak digunakan langsung sebagai nama file internal.
Hanya Mengandalkan Validasi Browser
Contohnya:
<input type="file" accept=".pdf,.jpg,.png">
Atribut accept membantu pengguna memilih file yang sesuai.
Namun, atribut tersebut bukan mekanisme keamanan.
Validasi tetap harus dilakukan oleh server.
🧪 Mini Practice
Gunakan aplikasi milik sendiri atau lingkungan lab yang memang memberikan izin untuk melakukan pengujian.
Kemudian analisis fitur upload menggunakan beberapa pertanyaan berikut:
- Jenis file apa yang diterima?
- Apakah ukuran file dibatasi?
- Apakah ekstensi diperiksa?
- Apakah tipe atau isi file diperiksa?
- Apakah nama file dibuat oleh server?
- Di mana file disimpan?
- Apakah file dapat diakses secara publik?
- Apakah pengguna harus login untuk mengakses file?
- Apakah authorization diperiksa?
- Apakah file disajikan sebagai download atau dirender oleh browser?
Hasil analisis dapat didokumentasikan menggunakan tabel berikut:
| Aspek | Kondisi | Risiko | Perbaikan |
|---|---|---|---|
| Tipe file | … | … | … |
| Ukuran | … | … | … |
| Nama file | … | … | … |
| Storage | … | … | … |
| Akses | … | … | … |
| Penyajian | … | … | … |
Tabel tersebut juga dapat digunakan sebagai bagian dari dokumentasi proyek PKL.
🎯 Kesimpulan
Insecure file upload tidak dapat dinilai hanya berdasarkan apakah file .php berhasil dieksekusi atau tidak.
Pada stack Node.js, file .php yang berhasil disimpan tidak otomatis diproses oleh PHP interpreter. Namun, mekanisme upload tetap perlu dianalisis dari berbagai sisi.
Beberapa aspek penting yang perlu diperhatikan adalah:
- tipe file,
- isi file,
- ukuran file,
- nama file,
- lokasi penyimpanan,
- kontrol akses,
- dan cara file disajikan kepada browser.
Dengan memahami alur tersebut, kita dapat melihat bahwa keamanan file upload bukan hanya tentang mencegah satu jenis file.
Tujuan utamanya adalah memastikan bahwa aplikasi hanya menerima file yang memang diperlukan, menyimpannya dengan aman, dan memberikan akses sesuai dengan hak pengguna.
📚 Referensi
MITRE CWE-434 — Unrestricted Upload of File with Dangerous Type
https://cwe.mitre.org/data/definitions/434.html
OWASP File Upload Cheat Sheet
https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
OWASP Unrestricted File Upload
https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload
DItulis oleh:Maulana Aldi Pradana
Mau Kuasai Insecure File Upload: Kenapa File .php Tidak Berhasil di Stack Node.js Sampai Bisa Praktik Langsung?
Materi ini juga kami ajarkan langsung di kelas Edusoft Center, dibimbing mentor, sampai kamu bisa praktik nyata — bukan cuma baca teori.
Tanya Kursus via WhatsApp Lihat contoh project nyata dari siswa kami →
