Sensitive Data Exposure — Security

Sensitive Data Exposure Salah satu risiko keamanan terbesar adalah mengekspos data sensitif secara tidak sengaja. Ini bisa terjadi karena konfigurasi yang…

Sensitive data exposure adalah bocornya data sensitif karena gak sengaja terkirim atau tercatat. Seringnya bukan karena dibobol, tapi karena kode mengirim lebih banyak dari yang perlu: response API yang memuat semua kolom, pesan error yang terlalu detail, atau log yang mencatat password. Bayangin kasir yang, saat memberi struk, ikut mencetak PIN dan saldo lengkapmu di situ. Gak ada yang membobol, kasirnya sendiri yang membocorkan.

🧪 Tebakan cepat: sebuah endpoint GET /api/user/5 menjalankan res.json(user) dengan user dari database apa adanya. Objek user punya kolom password_hash dan ssn. Apa yang ikut terkirim ke browser? Tebak dulu, jawabannya ada di bagian "Sumber kebocoran paling umum".

Jenis data sensitif

Data yang gak boleh terekspos ke pihak yang gak berhak:

Sumber kebocoran paling umum

1. Response API yang berlebihan. Mengirim seluruh objek dari database, termasuk kolom yang sensitif:

// BURUK: kirim semua kolom apa adanya
app.get("/api/user/:id", async (req, res) => {
  const user = await User.findById(req.params.id);
  res.json(user); // ikut password_hash, ssn, internal id!
});

// BAIK: pilih hanya kolom yang perlu (allowlist)
app.get("/api/user/:id", async (req, res) => {
  const user = await User.findById(req.params.id)
    .select("name email avatar createdAt");
  res.json(user);
});

2. Pesan error yang terlalu detail. Mengirim detail internal ke client:

// BURUK: bocorkan struktur database
{ "error": "SQLSTATE[42S02]: Table 'db_prod.users' doesn't exist" }

// BAIK: pesan generik ke user, detail dicatat di log server
{ "error": "Terjadi kesalahan internal. Silakan coba lagi." }

Stack trace di response memberi penyerang peta: nama file, library, versi, bahkan query. Di production, tampilkan pesan generik dan simpan detail di log server, bukan di response.

3. Logging yang tidak aman. Mencatat data sensitif ke log:

// BURUK: password terekspos di file log
console.log("Login attempt:", { email, password });

// BAIK: redact data sensitif
console.log("Login attempt:", { email, password: "[REDACTED]" });

4. File sensitif yang terekspos. File ini gak boleh bisa diakses publik:

.env            # kredensial dan secret
.git/           # seluruh sejarah kode
backup.sql      # dump database
phpinfo.php     # info server

Pencegahan

Laravel: sembunyikan kolom dengan $hidden

Di Laravel, property $hidden pada Model mencegah kolom muncul saat model di-serialize ke JSON:

class User extends Authenticatable
{
    protected $hidden = [
        "password",
        "remember_token",
    ];
}

⚠️ Jebakan yang sering ketemu

TL;DR: Sensitive data exposure adalah data sensitif (password, token, NIK, info internal) yang bocor karena terkirim atau tercatat tanpa sengaja. Sumbernya: response API yang mengirim seluruh objek (termasuk password_hash, ssn), pesan error dengan stack trace, log yang mencatat password, dan file seperti .env yang bisa diakses publik. Perbaikannya: allowlist kolom lewat API Resource/DTO, APP_DEBUG=false dan pesan error generik di production, redact log, blokir file sensitif, HTTPS, dan enkripsi at rest. Di Laravel, $hidden (misal password, remember_token) menyembunyikan kolom dari JSON. Pakai allowlist, bukan blacklist.

Yang akan kamu pelajari