Postingan blog ini membahas penerapan dukungan DevTools untuk men-debug masalah Kebijakan Keamanan Konten (CSP) dengan bantuan tab Masalah yang baru diperkenalkan.
Pekerjaan implementasi dilakukan selama 2 magang: 1. Selama fase pertama, kami membuat framework pelaporan umum dan mendesain pesan masalah untuk 3 masalah pelanggaran CSP. 2. Selama rilis kedua, kami menambahkan masalah Jenis Tepercaya bersama dengan beberapa fitur DevTools khusus untuk proses debug Jenis Tepercaya.
Apa yang dimaksud dengan Kebijakan Keamanan Konten?
Kebijakan Keamanan Konten (CSP) memungkinkan pembatasan perilaku tertentu di situs untuk meningkatkan keamanan. Misalnya, CSP dapat digunakan untuk melarang skrip inline atau melarang eval
, yang keduanya mengurangi platform serangan untuk serangan Pembuatan Skrip Lintas Situs (XSS). Untuk pengantar CSP yang mendetail, baca di sini.
CSP yang sangat baru adalah kebijakan Trusted Types(TT), yang memungkinkan analisis dinamis yang dapat secara sistematis mencegah berbagai jenis serangan injeksi di situs. Untuk mencapai hal ini, TT mendukung situs dalam memantau kode JavaScript-nya agar hanya mengizinkan jenis hal tertentu yang ditetapkan ke sink DOM seperti innerHTML.
Situs dapat mengaktifkan kebijakan keamanan konten dengan menyertakan header HTTP tertentu. Misalnya, header
content-security-policy: require-trusted-types-for 'script'; trusted-types default
mengaktifkan kebijakan TT untuk halaman.
Setiap kebijakan dapat beroperasi dalam salah satu mode berikut:
- mode yang diterapkan - setiap pelanggaran kebijakan adalah error,
- mode khusus laporan - yang melaporkan pesan error sebagai peringatan, tetapi tidak menyebabkan kegagalan di halaman web.
Menerapkan Masalah Kebijakan Keamanan Konten di tab Masalah
Tujuan pekerjaan ini adalah untuk meningkatkan pengalaman proses debug untuk masalah CSP. Saat mempertimbangkan masalah baru, tim DevTools secara kasar mengikuti proses ini:
- Menentukan cerita pengguna. Identifikasi serangkaian cerita pengguna di frontend DevTools yang membahas cara developer web harus menyelidiki masalah tersebut.
- Penerapan frontend. Berdasarkan cerita pengguna, identifikasi bagian informasi yang diperlukan untuk menyelidiki masalah di frontend (misalnya, permintaan terkait, nama cookie, baris dalam skrip atau file html, dll.).
- Deteksi masalah. Identifikasi tempat di browser tempat masalah dapat terdeteksi di Chrome dan instrumentasikan tempat tersebut untuk melaporkan masalah, termasuk informasi yang relevan dari langkah (2).
- Simpan dan tampilkan masalah. Simpan masalah di tempat yang sesuai dan sediakan untuk DevTools setelah dibuka
- Mendesain teks masalah. Buat teks penjelasan yang membantu developer web memahami, dan yang lebih penting, memperbaiki masalah
Langkah 1: menentukan cerita pengguna untuk Masalah CSP
Sebelum memulai pekerjaan penerapan, kami membuat dokumen desain dengan cerita pengguna untuk lebih memahami apa yang perlu kami lakukan. Misalnya, kami menuliskan cerita pengguna berikut:
Sebagai developer, yang baru saja menyadari bahwa beberapa bagian situs saya diblokir, saya ingin:- - ...menemukan tahu apakah CSP adalah alasan iframe / gambar di situs saya diblokir - ...mempelajari perintah CSP mana yang menyebabkan pemblokiran resource tertentu - ...mengetahui cara mengubah CSP situs saya untuk mengizinkan tampilan resource yang saat ini diblokir / eksekusi js yang saat ini diblokir.
Untuk mempelajari cerita pengguna ini, kami membuat beberapa contoh halaman web sederhana yang menampilkan pelanggaran CSP yang kami minati, dan mempelajari halaman contoh untuk memahami prosesnya sendiri. Berikut adalah beberapa contoh halaman web (buka demo dengan tab Masalah terbuka):
Dengan menggunakan proses ini, kami mengetahui bahwa lokasi sumber adalah bagian informasi yang paling penting untuk men-debug masalah CSP. Kami juga merasa bahwa menemukan iframe dan permintaan terkait dengan cepat berguna jika resource diblokir, dan link langsung ke elemen HTML di panel Elements di DevTools juga dapat berguna.
Langkah 2: implementasi frontend
Kami mengubah insight ini menjadi draf pertama informasi yang ingin kami sediakan untuk DevTools melalui Chrome DevTools Protocol (CDP):
Berikut adalah kutipan dari third_party/blink/public/devtools_protocol/browser_protocol.pdl
type ContentSecurityPolicyIssueDetails extends object
properties
# The url not included in allowed sources.
optional string blockedURL
# Specific directive that is violated, causing the CSP issue.
string violatedDirective
boolean isReportOnly
ContentSecurityPolicyViolationType contentSecurityPolicyViolationType
optional AffectedFrame frameAncestor
optional SourceCodeLocation sourceCodeLocation
optional DOM.BackendNodeId violatingNodeId
Definisi di atas pada dasarnya mengenkode struktur data JSON. File ini ditulis dalam bahasa sederhana yang disebut PDL (protocol data language). PDL digunakan untuk dua tujuan. Pertama, kita menggunakan PDL untuk membuat definisi TypeScript yang menjadi andalan frontend DevTools. Misalnya, definisi PDL di atas menghasilkan antarmuka TypeScript berikut:
export interface ContentSecurityPolicyIssueDetails {
/**
* The url not included in allowed sources.
*/
blockedURL?: string;
/**
* Specific directive that is violated, causing the CSP issue.
*/
violatedDirective: string;
isReportOnly: boolean;
contentSecurityPolicyViolationType: ContentSecurityPolicyViolationType;
frameAncestor?: AffectedFrame;
sourceCodeLocation?: SourceCodeLocation;
violatingNodeId?: DOM.BackendNodeId;
}
Kedua, dan mungkin yang lebih penting, kita membuat library C++ dari definisi yang menangani pembuatan dan pengiriman struktur data ini dari backend Chromium C++ ke frontend DevTools. Dengan library tersebut, objek ContentSecurityPolicyIssueDetails
dapat dibuat menggunakan potongan kode C++ berikut:
protocol::Audits::ContentSecurityPolicyIssueDetails::create()
.setViolatedDirective(d->violated_directive)
.setIsReportOnly(d->is_report_only)
.setContentSecurityPolicyViolationType(BuildViolationType(
d->content_security_policy_violation_type)))
.build();
Setelah memutuskan informasi yang ingin kami sediakan, kami perlu mencari tahu tempat untuk mendapatkan informasi ini dari Chromium.
Langkah 3: deteksi masalah
Agar informasi tersedia untuk Chrome DevTools Protocol (CDP) dalam format yang dijelaskan di bagian terakhir, kita perlu menemukan tempat informasi tersebut benar-benar tersedia di backend. Untungnya, kode CSP sudah memiliki bottleneck yang digunakan untuk mode khusus laporan, tempat kita dapat terhubung ke: ContentSecurityPolicy::ReportViolation
melaporkan masalah ke endpoint pelaporan (opsional) yang dapat dikonfigurasi di header HTTP CSP. Sebagian besar informasi yang ingin kami laporkan sudah tersedia, sehingga tidak ada perubahan besar di backend yang diperlukan agar instrumentasi kami berfungsi.
Langkah 4: simpan dan tampilkan masalah
Komplikasi kecilnya adalah fakta bahwa kita juga ingin melaporkan masalah yang terjadi sebelum DevTools dibuka, mirip dengan cara pesan konsol ditangani. Artinya, kami tidak langsung melaporkan masalah ke frontend, tetapi menggunakan penyimpanan yang diisi dengan masalah secara independen, terlepas dari apakah DevTools terbuka atau tidak. Setelah DevTools dibuka (atau, klien CDP lainnya dilampirkan), semua masalah yang direkam sebelumnya dapat diputar ulang dari penyimpanan.
Ini mengakhiri pekerjaan backend, dan sekarang kita perlu berfokus pada cara menampilkan masalah di frontend.
Langkah 5: mendesain teks masalah
Mendesain teks masalah adalah proses yang melibatkan beberapa tim selain tim kami sendiri, misalnya, kami sering mengandalkan insight dari tim yang menerapkan fitur (dalam hal ini adalah tim CSP) dan tentu saja tim DevRel, yang mendesain cara developer web menangani jenis masalah tertentu. Teks masalah biasanya mengalami beberapa penyempurnaan hingga selesai.
Biasanya, tim DevTools akan memulai dengan draf kasar dari apa yang mereka bayangkan:
## Header
Content Security Policy: include all sources of your resources in content security policy header to improve the functioning of your site
## General information
Even though some sources are included in the content security policy header, some resources accessed by your site like images, stylesheets or scripts originate from sources not included in content security policy directives.
Usage of content from not included sources is restricted to strengthen the security of your entire site.
## Specific information
### VIOLATED DIRECTIVES
`img-src 'self'`
### BLOCKED URLs
https://imgur.com/JuXCo1p.jpg
## Specific information
https://web.dev/strict-csp/
Setelah iterasi, kita akan sampai pada:
Seperti yang dapat Anda lihat, melibatkan tim fitur dan DevRel membuat deskripsi menjadi jauh lebih jelas dan akurat.
Masalah CSP di halaman Anda juga dapat ditemukan di tab yang secara khusus ditujukan untuk pelanggaran CSP.
Men-debug masalah Jenis Tepercaya
Bekerja dengan TT dalam skala besar dapat menjadi tantangan tanpa alat developer yang tepat.
Pencetakan konsol yang ditingkatkan
Saat menggunakan Objek Tepercaya, kita ingin menampilkan setidaknya jumlah informasi yang sama seperti untuk objek yang tidak tepercaya. Sayangnya, saat ini saat menampilkan Objek Tepercaya, tidak ada informasi tentang objek yang digabungkan yang ditampilkan.
Hal ini karena nilai yang ditampilkan di konsol diambil dari panggilan .valueOf()
pada objek secara default. Namun, dalam kasus Jenis Tepercaya, nilai yang ditampilkan tidak terlalu berguna. Sebagai gantinya, kita ingin memiliki sesuatu yang mirip dengan yang Anda dapatkan saat memanggil .toString()
. Untuk mencapai hal ini, kita perlu mengubah V8 dan Blink untuk memperkenalkan penanganan khusus bagi objek jenis tepercaya.
Meskipun karena alasan historis, penanganan kustom ini dilakukan di V8, pendekatan tersebut memiliki kelemahan penting. Ada banyak objek yang memerlukan tampilan kustom, tetapi jenisnya sama di tingkat JS. Karena V8 adalah JS murni, V8 tidak dapat membedakan konsep yang sesuai dengan Web API seperti Jenis Tepercaya. Oleh karena itu, V8 harus meminta bantuan penyertanya (Blink) untuk membedakannya.
Oleh karena itu, memindahkan bagian kode tersebut ke Blink atau penyempan tampaknya merupakan pilihan yang logis. Selain masalah yang terekspos, ada banyak manfaat lainnya:
- Setiap penyempan dapat memiliki pembuatan deskripsinya sendiri
- Membuat deskripsi melalui Blink API jauh lebih mudah
- Blink memiliki akses ke definisi asli objek. Jadi, jika kita menggunakan
.toString()
untuk membuat deskripsi, tidak ada risiko bahwa.toString()
mungkin didefinisikan ulang.
Jeda saat terjadi pelanggaran (dalam mode laporan saja)
Saat ini, satu-satunya cara men-debug pelanggaran TT adalah dengan menetapkan titik henti sementara pada pengecualian JS. Karena pelanggaran TT yang diterapkan akan memicu pengecualian, fitur ini dapat berguna. Namun, dalam skenario dunia nyata, Anda memerlukan kontrol yang lebih terperinci atas pelanggaran TT. Secara khusus, kami ingin membuat pemisahan hanya pada pelanggaran TT (bukan pengecualian lainnya), membuat pemisahan juga dalam mode hanya laporan, dan membedakan berbagai jenis pelanggaran TT.
DevTools sudah memiliki dukungan untuk berbagai titik henti sementara sehingga arsitekturnya cukup dapat diperluas. Menambahkan jenis titik henti sementara baru memerlukan perubahan di backend (Blink), CDP, dan frontend.
Kita harus memperkenalkan perintah CDP baru, sebut saja setBreakOnTTViolation
. Perintah ini akan digunakan oleh frontend untuk memberi tahu backend tentang jenis pelanggaran TT yang harus dilanggar. Backend, khususnya InspectorDOMDebuggerAgent
, akan menyediakan "probe", onTTViolation()
yang akan dipanggil setiap kali terjadi pelanggaran TT. Kemudian, InspectorDOMDebuggerAgent
akan memeriksa apakah pelanggaran tersebut harus memicu titik henti sementara, dan jika demikian, InspectorDOMDebuggerAgent
akan mengirim pesan ke frontend untuk menjeda eksekusi.
Apa yang sudah dilakukan dan apa yang akan dilakukan selanjutnya?
Sejak masalah yang dijelaskan di sini diperkenalkan, tab Masalah telah mengalami beberapa perubahan:
- Keterkaitannya dengan panel lain di DevTools telah ditingkatkan.
- Pelaporan sejumlah masalah lainnya telah dipindahkan ke tab Masalah: kontras rendah, aktivitas web tepercaya, mode quirks, attribution reporting API, dan masalah terkait CORS.
- Peluang untuk menyembunyikan masalah diperkenalkan
Ke depannya, kami berencana menggunakan tab Masalah untuk menampilkan lebih banyak masalah, yang akan memungkinkan Konsol untuk menghapus alur pesan error yang tidak dapat dibaca dalam jangka panjang.
Mendownload saluran pratinjau
Sebaiknya gunakan Chrome Canary, Dev, atau Beta sebagai browser pengembangan default Anda. Saluran pratinjau ini memberi Anda akses ke fitur DevTools terbaru, memungkinkan Anda menguji API platform web canggih, dan membantu Anda menemukan masalah di situs sebelum pengguna melakukannya.
Hubungi tim Chrome DevTools
Gunakan opsi berikut untuk membahas fitur baru, update, atau hal lain yang terkait dengan DevTools.
- Kirim masukan dan permintaan fitur kepada kami di crbug.com.
- Laporkan masalah DevTools menggunakan Opsi lainnya > Bantuan > Laporkan masalah DevTools di DevTools.
- Tweet ke @ChromeDevTools.
- Berikan komentar di video YouTube Yang baru di DevTools atau video YouTube Tips DevTools.