CSP Strict Dynamic Memindahkan Trust Script dari Daftar Host ke Root dengan Nonce

Halaman production dapat memakai kebijakan script-src yang ketat tetapi tetap bergantung pada bootstrap script yang membuat elemen script tambahan saat runtime. Host allowlist menangani arsitektur ini dengan mencantumkan setiap origin script yang diizinkan. Akibatnya, daftar tersebut terikat pada topologi deployment: memindahkan dependency ke host lain dapat memerlukan perubahan kebijakan, sedangkan mengizinkan host yang terlalu luas dapat memberi izin pada lebih banyak konten executable daripada yang dimaksud aplikasi.

Content Security Policy Level 3 menyediakan model trust berbeda melalui source expression 'strict-dynamic'. Ketika sebuah script diotorisasi oleh nonce atau hash yang valid, trust dapat diteruskan ke script yang dimuatnya melalui elemen script non-parser-inserted. Pada user agent yang mendukungnya, host-source dan scheme-source dalam kebijakan script tersebut tidak lagi mengendalikan delegated load itu.

Batas keamanannya ikut berpindah. Pertanyaan utamanya bukan lagi hanya lokasi jaringan mana yang boleh menyediakan JavaScript, tetapi elemen script awal mana yang mendapat otorisasi kriptografis dan kode apa yang dapat dieksekusi browser melalui trusted root tersebut.

Nonce mengotorisasi elemen, bukan server

CSP nonce adalah nilai per-response yang ditempatkan pada policy sekaligus pada elemen script yang memang ingin diizinkan oleh pembuat response. Untuk policy seperti:

Content-Security-Policy: script-src 'nonce-r4nd0mValue' 'strict-dynamic'

elemen script dengan nonce yang cocok dapat lolos pemeriksaan:

<script nonce="r4nd0mValue" src="/assets/bootstrap.js"></script>

Keputusan trust melekat pada elemen script tersebut. Nonce tidak menyatakan bahwa setiap script di bawah /assets/ tepercaya dan tidak mengotorisasi semua resource dari origin halaman. Nonce yang baru dan tidak dapat diprediksi biasanya dibuat untuk setiap response lalu ditempatkan pada policy dan elemen script yang memang dipilih aplikasi.

Granularitas ini menghindari kelemahan umum policy berbasis host. Jika origin yang diizinkan menyediakan banyak file, memiliki path yang dikendalikan user, atau mengekspos permukaan eksekusi bergaya JSONP, mengizinkan origin itu sebagai sumber script dapat mengotorisasi konten di luar dependency aplikasi yang sebenarnya.

Manfaat tersebut bergantung pada penempatan nonce yang tetap terkendali. Jika celah injection memungkinkan markup berbahaya memperoleh nonce valid, CSP tidak dapat membedakan elemen script berbahaya itu dari elemen yang memang dimaksudkan hanya berdasarkan nonce.

Strict dynamic mendelegasikan trust melalui elemen yang dibuat script

Expression 'strict-dynamic' mengubah apa yang terjadi setelah script awal diotorisasi oleh nonce atau hash. CSP Level 3 mendefinisikan propagasi trust untuk script yang dimuat melalui elemen script non-parser-inserted yang dibuat oleh trusted script.

Bootstrap loader dapat membuat node script, mengatur src, lalu memasukkannya ke document. Pada user agent yang menerapkan semantik strict-dynamic, descendant script tersebut dapat diizinkan karena loading chain-nya berasal dari trusted script, bahkan ketika host descendant tidak tercantum dalam policy.

Ini bukan aturan inheritance umum untuk semua jenis resource. Trusted script tidak memperoleh hak untuk melewati img-src, connect-src, frame-src, atau directive lain hanya karena strict-dynamic muncul di script-src. Mekanisme propagasinya khusus untuk eksekusi script sesuai aturan pemrosesan CSP yang berlaku.

Parser insertion juga merupakan batas penting. Elemen script yang sudah ada dalam markup hasil parsing tidak menjadi tepercaya hanya karena script dengan nonce dijalankan lebih dulu. Strict-dynamic dirancang untuk loading yang diprakarsai script, bukan trust menyeluruh terhadap markup berikutnya.

Model yang terbentuk menyerupai graph eksekusi. Sekumpulan kecil root yang diotorisasi nonce atau hash dapat membuat descendant tepercaya. Review keamanan karena itu perlu mengikuti authority root tersebut, termasuk perilaku loader, resolusi dependency, konstruksi URL, dan data yang dapat dipengaruhi attacker sebelum mencapai pembuatan script.

Host allowlist kehilangan authority pada browser yang mendukungnya

Policy kompatibilitas dapat memuat expression CSP ketat berbasis nonce sekaligus source tradisional:

script-src 'nonce-r4nd0mValue' 'strict-dynamic' https: 'self'

Dalam pemrosesan CSP Level 3 yang mengenali 'strict-dynamic' bersama nonce atau hash, host-source dan scheme-source seperti https: dan 'self' diabaikan untuk script loading yang diatur directive tersebut. Source itu masih dapat berguna sebagai fallback bagi implementasi CSP lama yang belum menerapkan semantik strict-dynamic.

Perbedaan operasional ini penting. String policy yang terlihat dapat tetap memuat host familiar, tetapi host tersebut belum tentu menjadi bagian dari keputusan otorisasi efektif di browser modern. Meninjau header sebagai allowlist datar dapat salah menggambarkan batas trust sebenarnya.

Tambahan kompatibilitas juga perlu diperhatikan. Fallback source untuk user agent lama dapat lebih luas daripada policy modern. Itu mungkin merupakan trade-off kompatibilitas yang diterima, tetapi tingkat perlindungan akhirnya ikut bergantung pada versi browser.

Delegated trust memperbesar authority loader

Strict-dynamic mengurangi beban pemeliharaan daftar host dependency rekursif, tetapi dengan sengaja memberi trusted script authority besar atas loading script berikutnya. Ini berguna untuk module loader, tag bootstrap, dan aplikasi yang lokasi dependency-nya berubah tanpa mengikuti template halaman.

Sifat yang sama mengubah konsekuensi kegagalan. Jika bootstrap script tepercaya menerima URL yang dikendalikan attacker lalu memasukkannya sebagai sumber script, browser dapat menganggap load tersebut sebagai bagian dari trusted chain. Host allowlist mungkin akan memblokir tujuan itu, tetapi strict-dynamic memang tidak memakai daftar host sebagai batas utama delegated load.

Policy karena itu mengasumsikan bahwa root dengan nonce atau hash layak menerima delegation authority. Validasi input di dalam root, integritas dependency, kontrol supply chain, dan tidak adanya script-loader gadget berbahaya menjadi semakin penting. CSP tidak dapat membuat keputusan loading sebuah trusted script menjadi aman setelah script itu diberi kemampuan memperluas trust.

Ini tidak berarti strict-dynamic sama dengan eksekusi script tanpa batas. Attacker tetap memerlukan jalur masuk ke trusted execution graph. Script parser-inserted sembarang tanpa nonce atau hash valid tetap berada di luar authorized root.

Kerahasiaan nonce bukan satu-satunya properti

Panduan nonce kadang disederhanakan menjadi kewajiban merahasiakan nilai acak. Unpredictability memang diperlukan, tetapi syarat yang lebih kuat adalah konten berbahaya tidak boleh memperoleh penempatan yang membawa otorisasi dan diterima browser.

Nonce muncul di document yang dikirim karena browser membutuhkannya untuk mengevaluasi elemen script. Desain ini tidak bergantung pada nonce sebagai credential jangka panjang yang tersembunyi dari seluruh kode halaman. Tujuannya adalah mencegah attacker yang dapat menyuntikkan markup tetapi tidak mengendalikan elemen script terotorisasi untuk sekadar menebak token per-response.

Server-side templating dapat merusak asumsi itu jika nonce direfleksikan ke markup yang dikendalikan attacker atau diterapkan tanpa seleksi ke semua elemen script. Kode DOM juga dapat menimbulkan masalah serupa jika trusted script menyalin elemen dengan nonce atau mengubah data tidak tepercaya menjadi descendant executable.

Penggunaan ulang nonce pada response yang tidak terkait memperpanjang periode ketika satu nilai yang diamati dapat tetap berguna. Pola yang dimaksud adalah nonce baru dan tidak dapat diprediksi untuk setiap response, hanya dipasangkan dengan elemen script yang dipilih aplikasi.

Root berbasis hash menukar state response dengan stabilitas konten

CSP dapat menetapkan trusted root dengan hash selain nonce. Hash source mengikat otorisasi ke isi script, bukan nilai acak per-response. Pendekatan ini cocok untuk bootstrap inline statis yang byte-nya stabil dan pipeline deployment dapat menjaga hash policy tetap sinkron.

Trade-off operasionalnya berbeda. Nonce membutuhkan koordinasi policy dan markup per-response tetapi tidak perlu menghitung ulang digest ketika isi script berubah. Hash tidak memerlukan pembuatan nonce untuk konten stabil, tetapi otorisasinya sensitif terhadap byte yang di-hash secara tepat.

Dengan strict-dynamic, keduanya dapat menjadi anchor delegated script loading ketika persyaratan CSP terpenuhi. Review keamanan tetap berpusat pada authority root: loader dengan hash yang benar tetap dapat memperluas trust ke arah berbahaya jika membangun URL script dari input hostile.

Reporting memperlihatkan pelanggaran policy, bukan intent policy

CSP reporting dapat menampilkan script load yang diblokir dan membantu menemukan masalah kompatibilitas saat deployment. Report-only policy juga dapat menunjukkan dampak sebelum enforcement diaktifkan. Mekanisme ini berguna saat bermigrasi dari policy berbasis host ke policy berbasis root nonce atau hash.

Report tidak membuktikan bahwa execution chain yang diizinkan aman. Descendant script yang diterima melalui strict-dynamic berperilaku sesuai policy, sehingga penerimaannya sendiri bukan violation yang perlu dilaporkan. Jika trusted loader membuat keputusan keamanan yang buruk, CSP mungkin tidak menghasilkan violation event.

Dengan demikian, enforcement telemetry berbeda dari analisis trust aplikasi. Violation report adalah bukti tentang tindakan yang ditolak CSP, bukan audit log setiap keputusan delegated trust dan bukan pengganti review terhadap penempatan nonce atau perilaku loader.

Batasnya adalah trusted script graph

Host allowlist mengekspresikan trust script sebagai lokasi jaringan. Strict-dynamic memungkinkan initial root yang lebih sempit sekaligus hubungan eksekusi transitif yang lebih luas. Pendekatan ini dapat menghapus enumerasi host dependency yang rapuh dan mengurangi paparan terhadap konten executable lain pada origin yang sama.

Trade-off-nya adalah authority yang terkonsentrasi. Bootstrap dengan nonce bukan sekadar satu file yang diizinkan; ia dapat menjadi root tempat trust script berikutnya mengalir. Input data, dependency resolver, jalur DOM insertion, dan supply chain-nya berada langsung pada batas eksekusi script browser.

CSP yang ketat memperoleh nilai keamanannya dari pemilihan root yang hati-hati, bukan hanya dari keberadaan keyword tertentu. Nonce atau hash membatasi eksekusi awal, strict-dynamic membawa trust itu melalui dynamic loading yang disengaja, dan aplikasi tetap bertanggung jawab mencegah data hostile mengarahkan trusted graph ke kode yang tidak dimaksudkan.