X-Content-Type-Options Memblokir MIME Type Sniffing

Response HTTP membawa header Content-Type yang menjelaskan media type representasi. Browser juga memiliki riwayat menginferensikan tipe dari byte response ketika tipe yang dideklarasikan tidak ada, keliru, atau ambigu. Inferensi tersebut dapat membantu konten lama, tetapi juga menciptakan batas eksekusi yang mungkin tidak dimaksudkan operator aplikasi.

X-Content-Type-Options: nosniff mempersempit batas itu. Untuk request destination yang tercakup aturan pemeriksaan MIME browser, response harus memiliki tipe terdeklarasi yang dapat diterima dan tidak bergantung pada content sniffing. Header ini sederhana, tetapi efeknya bergantung pada nilai Content-Type yang benar di seluruh aplikasi.

nosniff membuat tipe terdeklarasi menjadi konsekuensial

Server dapat mengirim kontrol ini sebagai response header:

X-Content-Type-Options: nosniff

Untuk script dan stylesheet, nosniff mengarahkan browser agar menolak response dengan MIME type terdeklarasi yang tidak valid untuk destination tersebut. Resource JavaScript karena itu perlu tiba dengan MIME type JavaScript yang sesuai, sedangkan stylesheet perlu tiba sebagai text/css.

Perhatikan request script yang menerima:

HTTP/1.1 200 OK
Content-Type: text/plain
X-Content-Type-Options: nosniff

Walaupun body response berisi sintaks JavaScript, browser tidak mendapat izin untuk menganggap deklarasi tipe sebagai sesuatu yang opsional. Ketidakcocokan tersebut tampak sebagai load yang diblokir, bukan diperbaiki melalui inferensi MIME.

Nilai keamanannya terletak pada perbedaan itu: deklarasi media type dari server ikut menentukan apakah konten dapat menempati destination yang dapat dieksekusi.

Header ini tidak menetapkan Content-Type yang benar

nosniff bukan mekanisme konfigurasi MIME. Header ini tidak memeriksa aplikasi lalu memilih media type yang dimaksud. Jika server memberi label text/plain pada JavaScript, mengaktifkan header dapat memperlihatkan kesalahan konfigurasi dengan membuat resource berhenti dimuat.

Deployment karena itu membutuhkan kedua kontrol:

Content-Type: text/javascript
X-Content-Type-Options: nosniff

Header pertama mendeklarasikan tipe representasi. Header kedua meminta browser agar tidak mengompensasi ketidakcocokan tertentu melalui sniffing.

Pemisahan ini penting pada sistem yang menyajikan file melalui beberapa lapisan. Application server mungkin mengirim tipe yang benar, sementara object store, aturan CDN, reverse proxy, atau static-file handler menetapkan tipe generik seperti application/octet-stream. Menambahkan nosniff di edge tanpa memeriksa jalur tersebut dapat mengubah cacat metadata yang tersembunyi menjadi kegagalan produksi.

Endpoint upload memerlukan media type yang disengaja

File yang dikendalikan pengguna perlu mendapat perhatian khusus. Layanan upload dapat menyimpan byte arbitrer lalu mengembalikannya melalui URL publik. Jika setiap objek disajikan dengan tipe yang longgar atau menyesatkan, perilaku browser menjadi lebih sulit diprediksi saat URL tersebut direferensikan dari konteks yang dapat dieksekusi.

Jalur penyajian yang lebih aman menetapkan media type berdasarkan kebijakan aplikasi yang tepercaya dan memperlakukan file tidak tepercaya sebagai data, bukan aset aplikasi yang dapat dieksekusi. Jika suatu tipe file tidak ditujukan untuk berjalan sebagai script atau CSS, metadata response juga tidak seharusnya menyatakannya demikian.

nosniff memperkuat batas ini untuk destination yang tercakup, tetapi tidak membersihkan konten upload, memvalidasi format file, menghapus HTML aktif, atau mengisolasi dokumen berbahaya. Sistem upload tetap memerlukan kontrol sesuai threat model, misalnya origin terpisah, content disposition yang restriktif, otorisasi, validasi file, dan content security policy jika relevan.

Status code yang benar tetap penting

Error response juga dapat menghasilkan ketidakcocokan MIME. URL script dapat mengembalikan halaman error HTML melalui response handler generik:

HTTP/1.1 404 Not Found
Content-Type: text/html
X-Content-Type-Options: nosniff

Status 404 sudah menyatakan bahwa resource yang diminta tidak tersedia. Tipe HTML secara akurat menjelaskan representasi error. Menjaga keduanya tetap benar membuat perilaku browser, observability, dan diagnosis insiden lebih dapat diprediksi.

Masalah muncul ketika lapisan routing mengembalikan halaman fallback HTML dengan 200 OK untuk path aset yang tidak ada. nosniff dapat mencegah response tersebut dikonsumsi sebagai script atau stylesheet, tetapi cacat routing masih tetap ada. Security header seharusnya membantu menampakkan invariant yang rusak, bukan menjadi alasan untuk mempertahankannya.

nosniff bukan pengganti CSP

Content Security Policy dan X-Content-Type-Options bekerja pada lapisan berbeda. CSP dapat membatasi origin atau source expression yang diizinkan memasok script dan resource lain. nosniff membatasi interpretasi tipe untuk request destination yang tercakup.

Sebuah response dapat lolos pemeriksaan MIME tetapi tetap berasal dari sumber yang tidak semestinya dipercaya aplikasi. Sebaliknya, URL script yang diizinkan CSP dapat gagal karena response membawa MIME type yang tidak dapat diterima ketika nosniff aktif.

Menggunakan kedua kontrol menghasilkan pemeriksaan independen: otorisasi sumber dan konsistensi media type. Keduanya tidak mengubah konten arbitrer menjadi kode yang aman.

Uji setiap jalur pengiriman aset

Header yang ditambahkan ke response HTML utama tidak membuktikan bahwa script, stylesheet, objek upload, aset hasil generate, atau error response membawa metadata yang sesuai. Setiap jalur pengiriman dapat melewati infrastruktur berbeda.

Pemeriksaan representatif perlu melihat response akhir setelah redirect dan caching layer. Contohnya:

curl -I https://example.com/assets/app.js
curl -I https://example.com/assets/site.css

Hasilnya perlu dinilai sebagai pasangan: Content-Type yang dimaksud dan keberadaan X-Content-Type-Options: nosniff. Developer tools browser kemudian dapat mengonfirmasi apakah load halaman yang nyata mengalami pemblokiran MIME.

Rollout paling aman dilakukan dengan memperbaiki media type yang keliru sebelum header diterapkan secara luas. Setelah metadata konsisten, nosniff menjadikan konsistensi tersebut sebagai batas yang ditegakkan browser untuk destination yang tercakup.