Mengimplementasikan proses debug CSP dan Jenis Tepercaya di Chrome DevTools

Kateryna Prokopenko
Kateryna Prokopenko
Alfonso Castaño
Alfonso Castaño

Postingan blog ini membahas tentang implementasi dukungan DevTools untuk men-debug masalah Kebijakan Keamanan Konten (CSP) dengan bantuan tab Masalah yang baru-baru ini diperkenalkan.

Pekerjaan implementasi dilakukan selama 2 kali magang: 1. Selama yang pertama, kami membuat framework pelaporan umum dan mendesain pesan masalah untuk 3 masalah pelanggaran CSP. 2. Dalam proses kedua, kami menambahkan masalah Trusted Type bersama beberapa fitur khusus DevTools untuk proses debug Jenis Tepercaya.

Apa itu 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 permukaan serangan untuk serangan Pembuatan Skrip Lintas Situs (XSS). Untuk pengantar CSP mendetail, baca di sini.

CSP yang sangat baru adalah kebijakan Jenis Tepercaya(TT), yang memungkinkan analisis dinamis yang secara sistematis dapat mencegah kelas besar serangan injeksi di situs. Untuk mencapai hal ini, TT mendukung situs web dalam mengatur kode JavaScript-nya agar hanya mengizinkan jenis hal tertentu untuk ditetapkan ke sink DOM seperti innerHTML.

Situs web 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 - yang merupakan error untuk setiap pelanggaran kebijakan,
  • mode hanya laporan - yang melaporkan pesan error sebagai peringatan, tetapi tidak menyebabkan kegagalan di halaman web.

Mengimplementasikan Masalah Kebijakan Keamanan Konten di tab Masalah

Tujuan pekerjaan ini adalah untuk meningkatkan pengalaman proses debug untuk masalah CSP. Ketika mempertimbangkan masalah baru, tim DevTools kurang lebih akan mengikuti proses ini:

  1. Mendefinisikan cerita pengguna. Identifikasi serangkaian cerita pengguna di frontend DevTools yang mencakup bagaimana developer web perlu menyelidiki masalah tersebut.
  2. Implementasi frontend. Berdasarkan cerita pengguna, identifikasi informasi mana yang diperlukan untuk penyelidikan masalah di front-end (misalnya permintaan terkait, nama cookie, baris dalam skrip atau file html, dll.).
  3. Pendeteksian masalah. Identifikasi bagian di browser tempat masalah dapat dideteksi di Chrome dan instrumentasikan tempat untuk melaporkan masalah termasuk informasi yang relevan dari langkah (2).
  4. Simpan dan tampilkan masalah. Simpan masalah di tempat yang sesuai dan buat masalah tersedia di DevTools setelah dibuka
  5. Mendesain teks masalah. Buatlah teks penjelasan yang membantu pengembang web memahami, dan yang lebih penting memperbaiki masalah tersebut

Langkah 1: menentukan cerita pengguna untuk Masalah CSP

Sebelum memulai pekerjaan implementasi, 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:- - ...mengetahui apakah CSP merupakan alasan pemblokiran iframe / gambar di situs saya - ...pelajari perintah CSP mana yang menyebabkan pemblokiran resource tertentu - ...mengetahui cara mengubah CSP situs saya untuk mengizinkan tampilan resource / eksekusi js yang saat ini diblokir.


Untuk mengeksplorasi cerita pengguna ini, kami membuat beberapa contoh halaman web sederhana yang menunjukkan pelanggaran CSP yang kami minati, dan menjelajahi halaman contoh untuk memahami prosesnya sendiri. Berikut adalah beberapa contoh halaman web (buka demo dengan tab Masalah terbuka):

Menggunakan proses ini, kita mempelajari bahwa lokasi sumber adalah informasi terpenting untuk men-debug masalah CSP. Kami juga merasa perlu untuk dengan cepat menemukan iframe dan permintaan terkait jika resource diblokir, dan link langsung ke elemen HTML di panel Elements pada DevTools juga dapat berguna.

Langkah 2: implementasi {i>front-end<i}

Kami mengubah insight ini menjadi draf informasi pertama 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. Laporan ini ditulis dalam bahasa sederhana yang disebut PDL (bahasa data protokol). PDL digunakan untuk dua tujuan. Pertama, kita menggunakan PDL untuk menghasilkan definisi TypeScript yang diandalkan front-end 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 menghasilkan library C++ dari definisi yang menangani pembuatan dan pengiriman struktur data ini dari backend Chromium C++ ke front-end DevTools. Dengan library tersebut, objek ContentSecurityPolicyIssueDetails dapat dibuat menggunakan bagian 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 menentukan informasi yang ingin tersedia, kami perlu mengeksplorasi 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 lokasi tempat informasi sebenarnya tersedia di backend. Untungnya, kode CSP sudah memiliki leher botol 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, jadi tidak ada perubahan besar pada backend yang diperlukan agar instrumentasi kami dapat berfungsi.

Langkah 4: simpan dan tampilkan masalah

Detail kecil adalah fakta bahwa kami juga ingin melaporkan masalah yang terjadi sebelum DevTools dibuka, mirip dengan cara menangani pesan konsol. Ini berarti kita tidak langsung melaporkan masalah ke front-end, namun menggunakan penyimpanan yang diisi dengan masalah secara independen mengenai apakah DevTools terbuka atau tidak. Setelah DevTools dibuka (atau, dalam hal ini, klien CDP lain terpasang), semua masalah yang telah direkam sebelumnya dapat di-replay dari penyimpanan.

Ini mengakhiri pekerjaan {i>back-end<i}, dan kami sekarang perlu fokus pada cara memunculkan masalah di {i>front-end<i}.

Langkah 5: merancang 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 seharusnya 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 kemudian sampai di:

ALT_TEXT_HERE

Seperti yang Anda lihat, melibatkan tim fitur dan DevRel membuat deskripsi jauh lebih jelas dan tepat.

Masalah CSP di halaman Anda juga dapat ditemukan di tab khusus yang dikhususkan untuk pelanggaran CSP.

Men-debug masalah Tipe Tepercaya

Bekerja dengan TT dalam skala besar dapat menjadi sulit tanpa alat developer yang tepat.

Peningkatan pencetakan konsol

Saat bekerja dengan {i>Trusted Objects<i}, kita ingin menampilkan setidaknya jumlah informasi yang sama dengan pasangan yang tidak tepercaya. Sayangnya, saat menampilkan Objek Tepercaya, tidak ada informasi tentang objek yang digabungkan yang ditampilkan.

Hal ini karena nilai yang ditampilkan di konsol diambil dari pemanggilan .valueOf() pada objek secara default. Namun, untuk Jenis Tepercaya, nilai yang ditampilkan tidak terlalu berguna. Sebagai gantinya, kami ingin memiliki sesuatu yang mirip dengan yang Anda dapatkan saat memanggil .toString(). Untuk mencapai hal ini, kita perlu memodifikasi V8 dan Blink untuk memperkenalkan penanganan khusus untuk objek tipe tepercaya.

Meskipun karena alasan historis, penanganan kustom ini dilakukan di V8, pendekatan seperti itu memiliki kelemahan penting. Ada banyak objek yang memerlukan tampilan kustom tetapi yang jenisnya sama di tingkat JS. Karena V8 adalah JS murni, V8 tidak dapat membedakan konsep yang sesuai dengan API Web seperti Jenis Tepercaya. Karena alasan itu, V8 harus meminta bantuan penyematnya (Blink) untuk membedakannya.

Oleh karena itu, memindahkan bagian kode tersebut ke Blink atau penyemat apa pun terdengar seperti pilihan logis. Selain masalah yang terekspos, ada banyak manfaat lainnya:

  • Setiap penyemat dapat memiliki pembuatan deskripsinya sendiri
  • Pembuatan deskripsi jauh lebih mudah melalui Blink API
  • Blink memiliki akses ke definisi asli objek. Jadi, jika kita menggunakan .toString() untuk membuat deskripsi, tidak ada risiko .toString() dapat ditentukan ulang.

Menerobos pelanggaran (dalam mode laporan saja)

Saat ini, satu-satunya cara untuk melakukan proses debug pelanggaran TT adalah dengan menetapkan titik henti sementara di pengecualian JS. Karena pelanggaran TT yang diterapkan akan memicu pengecualian, fitur ini mungkin akan berguna. Namun, dalam skenario dunia nyata, Anda memerlukan kontrol yang lebih mendetail atas pelanggaran TT. Secara khusus, kami ingin menguraikan hanya pelanggaran TT (bukan pengecualian lainnya), mengelompokkan juga ke mode laporan saja, dan membedakan antara berbagai jenis pelanggaran TT.

DevTools sudah memiliki dukungan untuk berbagai macam titik henti sementara sehingga arsitekturnya cukup dapat diperluas. Penambahan jenis titik henti sementara baru memerlukan perubahan pada 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 dipecahkan. Backend, khususnya InspectorDOMDebuggerAgent, akan menyediakan "pemeriksaan", onTTViolation() yang akan dipanggil setiap kali pelanggaran TT terjadi. Kemudian, InspectorDOMDebuggerAgent akan memeriksa apakah pelanggaran tersebut harus memicu titik henti sementara. Jika demikian, kode akan mengirim pesan ke frontend untuk menjeda eksekusi.

Apa yang telah dilakukan dan apa langkah selanjutnya?

Sejak masalah yang dijelaskan di sini diperkenalkan, tab Masalah telah mengalami beberapa perubahan:

Ke depannya, kami berencana menggunakan tab Issues untuk menampilkan lebih banyak masalah, sehingga memungkinkan penghapusan muatan Konsol dari alur pesan error yang tidak dapat dibaca dalam jangka panjang.

Mendownload saluran pratinjau

Pertimbangkan untuk menggunakan Chrome Canary, Dev, atau Beta sebagai browser pengembangan default Anda. Saluran pratinjau ini memberi Anda akses ke fitur DevTools terbaru, menguji API platform web tercanggih, dan menemukan masalah di situs Anda sebelum pengguna melakukannya.

Menghubungi tim Chrome DevTools

Gunakan opsi berikut untuk membahas fitur dan perubahan baru di postingan, atau hal lain yang berkaitan dengan DevTools.

  • Kirim saran atau masukan kepada kami melalui crbug.com.
  • Laporkan masalah DevTools menggunakan Opsi lainnya   Lainnya   > Bantuan > Laporkan masalah DevTools di DevTools.
  • Tweet di @ChromeDevTools.
  • Berikan komentar di video YouTube Apa yang baru di DevTools atau video YouTube Tips DevTools.