Tiga endpoint di LabKeu membalas permintaan apa pun dengan detail teknis milik server: nama skema database, isi query SQL yang gagal, nama tabel beserta indeksnya, sampai path lengkap file di dalam container. Tidak ada exploitasi rumit, cukup satu karakter kutip yang tidak ditutup, dan server menulis sendiri peta internalnya di layar penyerang. Dari balasan ini saja penyerang tahu aplikasi memakai Express + Node.js, berjalan di `/usr/src/app` (struktur khas Docker), memakai MySQL dengan skema `labkeu`, dan punya tabel `users` dengan indeks `users.username`.
Mengapa Celah Ini Kritis?
Mengapa Information Disclosure Perlu Diperhatikan?
Information disclosure sering dianggap memiliki dampak terbatas karena tidak secara langsung menyebabkan perubahan data atau pengambilalihan akun. Namun, informasi teknis yang terekspos dapat membantu proses pemetaan aplikasi dan mempermudah pengujian terhadap kerentanan lainnya.
Pada studi kasus LabKeu, informasi yang diberikan melalui pesan error memiliki beberapa implikasi keamanan.
Mengurangi Proses Enumerasi
Pesan error memberikan informasi mengenai nama skema, tabel, kolom, dan struktur query yang digunakan aplikasi. Tanpa informasi tersebut, penguji perlu melakukan proses enumerasi untuk memperoleh struktur yang sama.
Dengan demikian, kebocoran informasi dapat mengurangi jumlah percobaan yang diperlukan untuk memahami struktur aplikasi dan database.
Mengungkap Komponen Aplikasi
Stack trace menampilkan path beberapa library, antara lain:
node_modules/body-parser/...
node_modules/multer/...
raw-body/index.jsInformasi tersebut dapat digunakan untuk mengidentifikasi komponen yang digunakan aplikasi dan selanjutnya membantu proses identifikasi versi maupun potensi kerentanan yang berkaitan dengan komponen tersebut.
Menunjukkan Konfigurasi Aplikasi
Stack trace yang ditampilkan kepada pengguna menunjukkan bahwa aplikasi masih memungkinkan detail kesalahan ditampilkan pada respons.
Pada kasus ini, NODE_ENV tidak diatur ke production, sehingga Express menggunakan mekanisme error handler development yang dapat menampilkan stack trace secara lengkap.
Mengungkap Konfigurasi Security Header
Respons aplikasi juga menunjukkan bahwa sejumlah security header belum diterapkan. Header seperti Content-Security-Policy, X-Frame-Options, dan X-Content-Type-Options tidak ditemukan pada respons.
Selain itu, X-Powered-By: Express masih dikirimkan sehingga framework yang digunakan aplikasi dapat diidentifikasi dari sisi klien.
Mendukung Identifikasi Kerentanan Lain
Informasi yang diperoleh dari pesan error juga dapat digunakan untuk memvalidasi dugaan terhadap kerentanan lain.
Dalam studi kasus ini, error database memberikan informasi mengenai struktur query dan bagaimana input pengguna diproses. Kondisi tersebut membantu mengonfirmasi adanya indikasi SQL Injection pada endpoint /login-noportal.
Akar Masalah pada Aplikasi
Sumber utama kebocoran informasi pada LabKeu berasal dari mekanisme penanganan error yang menampilkan detail kesalahan server secara langsung kepada pengguna.
Pesan Error Database Ditampilkan kepada Pengguna
Pada routes/auth.js, pesan error database dimasukkan langsung ke dalam respons:
// routes/auth.js:48-51
} catch (e) {
// Pesan error database ditampilkan kepada pengguna
res.render("login-noportal", {
error: "Query error: " + e.message
});
}Pola yang sama ditemukan pada proses registrasi:
// routes/auth.js:67-69
} catch (e) {
res.render("register", {
error: "Gagal daftar: " + e.message
});
}Penggunaan e.message secara langsung menyebabkan detail kesalahan dari database dapat diteruskan kepada pengguna.
NODE_ENV Tidak Dikonfigurasi sebagai Production
Pada server.js, variabel NODE_ENV tidak ditetapkan ke production. Kondisi tersebut menyebabkan Express menggunakan mekanisme error handler development yang dapat menampilkan stack trace ketika terjadi kesalahan.
Security Header Belum Diterapkan
Aplikasi tidak menggunakan helmet maupun konfigurasi security header yang memadai. Selain itu, header X-Powered-By: Express masih terdapat pada respons aplikasi.
Kondisi tersebut menambah informasi yang dapat digunakan untuk mengidentifikasi teknologi yang digunakan oleh aplikasi.
Pengujian Information Disclosure
Pengujian dilakukan dari mesin penguji terhadap aplikasi LabKeu. Alamat target yang digunakan dalam pengujian adalah:
192.168.1.19:3000
export TARGET="http://192.168.1.19:3000"Alamat tersebut dapat disesuaikan dengan alamat IP target pada lingkungan pengujian.
1. Menguji Kebocoran Struktur Query SQL
Pengujian pertama dilakukan dengan mengirim karakter kutip pada parameter username.
curl -s -X POST "$TARGET/login-noportal" \
--data-urlencode "username='" \
--data-urlencode "password=x"
Respons aplikasi menunjukkan pesan error SQL:
Query error: You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near
'x' AND account_type = 'perusahaan'' at line 1
Respons tersebut mengungkap beberapa informasi teknis, yaitu:
- Database yang digunakan adalah MySQL.
- Query menggunakan kolom
username,password, danaccount_type. - Struktur query yang gagal dapat diketahui melalui pesan error.
- Nilai literal yang digunakan dalam query juga ikut ditampilkan.
Kondisi tersebut menunjukkan bahwa pesan error database tidak seharusnya diteruskan secara langsung kepada pengguna.
2. Menguji Kebocoran Nama Skema Database
Pengujian berikut digunakan untuk mengetahui apakah nama skema database dapat diperoleh melalui pesan error.
curl -s -X POST "$TARGET/login-noportal" \
--data-urlencode "username=x' AND (SELECT 1 FROM nonexistent_table)=1 -- " \
--data-urlencode "password=x"Respons yang diperoleh:
Query error: Table 'labkeu.nonexistent_table' doesn't exist
Respons tersebut mengungkap nama skema database:
labkeuInformasi mengenai nama skema merupakan bagian dari struktur internal database yang seharusnya tidak ditampilkan pada respons kepada pengguna.
3. Menguji Kebocoran Nama Tabel dan Indeks
Pengujian selanjutnya dilakukan melalui endpoint registrasi:
curl -s -X POST "$TARGET/register" \
--data-urlencode "nama_lengkap=Uji" \
--data-urlencode "username=user_a" \
--data-urlencode "password=x12345" \
--data-urlencode "account_type=individu"Apabila username telah digunakan, aplikasi memberikan respons:
Gagal daftar: Duplicate entry 'user_a' for key 'users.username'
Respons tersebut mengungkap:
- Nama tabel:
users - Nama kolom:
username - Nama indeks atau constraint:
users.username
Informasi tersebut menunjukkan bahwa kolom username memiliki constraint UNIQUE.
Mau Kuasai Menguji Information Disclosure pada Aplikasi Web: Studi Kasus LabKeu 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 →
4. Menguji Kebocoran Stack Trace
Untuk menguji apakah aplikasi menampilkan stack trace, dikirimkan data JSON yang tidak valid ke endpoint /login.
curl -s -i -X POST "$TARGET/login" \
-H 'Content-Type: application/json' -d '{"bad"'Respons HTTP 400 yang diperoleh dapat berisi:
SyntaxError: Expected ':' after property name in JSON at position 6
at JSON.parse (<anonymous>)
at parse (/usr/src/app/node_modules/body-parser/lib/types/json.js:96:19)
at /usr/src/app/node_modules/body-parser/lib/read.js:128:18
at invokeCallback (/usr/src/app/node_modules/raw-body/index.js:238:16)
...
tack trace tersebut mengungkap beberapa informasi internal aplikasi, antara lain:
- Path aplikasi:
/usr/src/app - Library
body-parser - Library
raw-body - Struktur direktori aplikasi di dalam container
Informasi tersebut seharusnya hanya tersedia pada log internal aplikasi dan tidak dikirimkan kepada pengguna.
5. Menguji Kebocoran Stack Trace pada Endpoint Upload
Endpoint upload memerlukan sesi login terlebih dahulu. Cookie sesi dapat disimpan menggunakan perintah berikut:
curl -s -c /tmp/cj -o /dev/null -X POST "$TARGET/login-noportal" \
--data-urlencode "username=user_a" \
--data-urlencode "password=password123"Selanjutnya, buat file pengujian:
echo x > /tmp/probe.txt
Kirimkan file dengan nama field yang tidak sesuai:
curl -s -b /tmp/cj -i -X POST "$TARGET/upload" \
-F "file=@/tmp/probe.txt"Respons HTTP 500 dapat menampilkan:
MulterError: Unexpected file field
at wrappedFileFilter (/usr/src/app/node_modules/multer/index.js:123:19)
at Multipart.<anonymous> (/usr/src/app/node_modules/multer/lib/make-middleware.js:344:7)
at /usr/src/app/node_modules/busboy/lib/types/multipart.js:358:14
Respons tersebut kembali menunjukkan path aplikasi dan komponen yang digunakan, yaitu multer dan busboy.
6. Memeriksa Security Header
Pemeriksaan terhadap header respons dilakukan menggunakan:
curl -s -D - -o /dev/null -b /tmp/cj "$TARGET/dashboard"
Respons:
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 1888
ETag: W/"760-ZU48vH+kV38PsgR6M1tP4gSU92c"
Date: Fri, 02 Oct 2026 13:10:32 GMT
Connection: keep-alive
Keep-Alive: timeout=5Beberapa security header yang tidak ditemukan adalah:
| Header | Status |
|---|---|
Content-Security-Policy | Tidak ada |
X-Frame-Options | Tidak ada |
X-Content-Type-Options | Tidak ada |
Strict-Transport-Security | Tidak ada |
Referrer-Policy | Tidak ada |
X-Powered-By | Ada |
Selain itu, cookie connect.sid ditemukan tanpa flag HttpOnly dan Secure.
Dampak Information Disclosure
Information disclosure pada LabKeu memberikan beberapa dampak terhadap keamanan aplikasi:
| Aspek | Dampak |
|---|---|
| Kerahasiaan | Struktur internal aplikasi, database, dan komponen yang digunakan dapat diketahui oleh pihak yang tidak berwenang. |
| Proses pengujian | Informasi teknis mengurangi kebutuhan enumerasi terhadap struktur aplikasi. |
| Risiko terhadap kerentanan lain | Informasi yang bocor dapat membantu proses validasi dan eksploitasi kerentanan lain. |
| Infrastruktur | Path container dan komponen aplikasi memberikan informasi mengenai lingkungan deployment. |
| Kepatuhan | Informasi teknis internal yang terekspos dapat menjadi temuan dalam proses audit keamanan. |
Cara Mencegah Information Disclosure
1. Jangan Menampilkan Pesan Error Mentah
Detail error sebaiknya dicatat pada log server dan tidak dikirimkan kepada pengguna.
// routes/auth.js
} catch (e) {
console.error("[login-noportal]", e);
res.render("login-noportal", {
error: "Terjadi gangguan, silakan coba lagi."
});
}Dengan pendekatan tersebut, administrator tetap memperoleh informasi teknis melalui log tanpa mengeksposnya kepada pengguna.
2. Mengaktifkan Mode Production
Atur NODE_ENV menjadi production pada environment aplikasi:
NODE_ENV=productionPada Docker Compose atau Dockerfile, konfigurasi tersebut dapat ditempatkan pada bagian environment sesuai konfigurasi deployment.
Dengan mode production, Express tidak menampilkan stack trace secara detail pada respons kepada pengguna.
3. Menerapkan Security Header
Gunakan helmet untuk membantu menerapkan sejumlah security header:
npm install helmetKemudian pada server.js:
const helmet = require("helmet");
app.use(helmet());
app.disable("x-powered-by");Konfigurasi tersebut membantu menerapkan berbagai header keamanan sekaligus menghilangkan X-Powered-By dari respons.
4. Melakukan Validasi Input Sebelum Query
Input pengguna harus divalidasi sebelum diproses oleh database. Penggunaan prepared statement atau parameterized query juga diperlukan untuk mencegah input pengguna memengaruhi struktur query SQL.
Selain mengurangi risiko SQL Injection, pendekatan tersebut dapat mengurangi kemungkinan input yang tidak valid menghasilkan error database yang kemudian ditampilkan kepada pengguna.
5. Menerapkan Error Handler Terpusat
Penanganan error dapat dilakukan melalui middleware pada tingkat aplikasi:
app.use((err, req, res, next) => {
const ref = Date.now().toString(36);
console.error(`[${ref}]`, err);
res.status(500).json({
error: "Terjadi kesalahan server",
ref
});
});Kode referensi dapat digunakan untuk menghubungkan respons pengguna dengan detail error yang tersimpan pada log server.
6. Melakukan Pengujian Regresi
Setelah perbaikan diterapkan, pengujian perlu dilakukan kembali untuk memastikan detail teknis tidak lagi muncul pada respons.
Pengujian otomatis dapat digunakan untuk memastikan respons tidak mengandung informasi seperti:
node_modules
SQLSTATE
Query error
/usr/src/appKesimpulan
Studi kasus pada LabKeu menunjukkan bahwa information disclosure dapat terjadi ketika aplikasi menampilkan detail kesalahan internal secara langsung kepada pengguna.
Melalui beberapa pengujian, ditemukan kebocoran berupa struktur query SQL, nama skema database, nama tabel dan indeks, path aplikasi di dalam container, serta informasi mengenai library yang digunakan.
Meskipun information disclosure tidak secara langsung memberikan akses terhadap data, informasi tersebut dapat membantu proses pemetaan aplikasi dan mendukung pengujian terhadap kerentanan lainnya.
Mitigasi dapat dilakukan dengan menerapkan error handling yang tepat, mengaktifkan NODE_ENV=production, menerapkan security header, melakukan validasi input, menggunakan prepared statement, serta memastikan detail kesalahan hanya tersedia melalui log internal aplikasi.
Penulis:
Mau Kuasai Menguji Information Disclosure pada Aplikasi Web: Studi Kasus LabKeu 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 →
