Mengimplementasikan proses debug CSP dan Jenis Tepercaya di Chrome DevTools

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

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

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

Apa itu Kebijakan Keamanan Konten?

Kebijakan Keamanan Konten (CSP) memungkinkan untuk membatasi perilaku tertentu di situs guna 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 serangkaian serangan injeksi yang besar 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 dapat mengaktifkan kebijakan keamanan konten dengan menyertakan header HTTP tertentu. Misalnya, {i>header<i} content-security-policy: require-trusted-types-for 'script'; trusted-types default mengaktifkan kebijakan TT untuk suatu halaman.

Setiap kebijakan dapat beroperasi dalam salah satu mode berikut:

  • enforced mode - di mana setiap pelanggaran kebijakan merupakan error,
  • mode hanya laporan - yang melaporkan pesan error sebagai peringatan, tetapi tidak menyebabkan kegagalan di halaman web.

Menerapkan Masalah Kebijakan Keamanan Konten di tab Masalah

Tujuan dari pekerjaan ini adalah untuk meningkatkan pengalaman {i>debugging<i} untuk masalah CSP. Saat mempertimbangkan masalah baru, tim DevTools kurang lebih mengikuti proses ini:

  1. Mendefinisikan cerita pengguna. Identifikasi serangkaian cerita pengguna di front-end DevTools yang mencakup bagaimana developer web perlu menyelidiki masalah.
  2. Penerapan frontend. Berdasarkan cerita pengguna, identifikasi bagian informasi yang diperlukan untuk penyelidikan masalah di bagian depan (misalnya permintaan terkait, nama cookie, baris dalam file html atau skrip, dll).
  3. Pendeteksian masalah. Identifikasi tempat di browser tempat masalah dapat dideteksi pada 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 sediakan untuk DevTools setelah dibuka
  5. Mendesain teks masalah. Menemukan teks penjelasan yang akan membantu developer web memahami, dan yang lebih penting lagi, memperbaiki masalahnya

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 dilakukan. Misalnya, kami menuliskan cerita pengguna berikut:


Sebagai developer yang baru menyadari bahwa beberapa bagian dari situs saya diblokir, saya ingin:- - ...cari tahu apakah CSP adalah alasan untuk iframe / gambar yang diblokir di situs saya - ...mempelajari direktif CSP mana yang menyebabkan pemblokiran resource tertentu - ...tahu cara mengubah CSP situs saya untuk mengizinkan tampilan resource / eksekusi js yang saat ini diblokir.


Untuk mempelajari cerita pengguna ini, kami membuat beberapa contoh halaman web sederhana yang menunjukkan pelanggaran CSP yang kami minati, dan mempelajari halaman contoh agar lebih memahami prosesnya. Berikut ini beberapa contoh halaman web (buka demo dengan tab Masalah dalam keadaan terbuka):

Melalui proses ini, kita mempelajari bahwa lokasi sumber adalah informasi terpenting untuk melakukan proses debug masalah CSP. Kami juga merasakan manfaat untuk menemukan iframe dan permintaan terkait dengan cepat jika resource diblokir, dan link langsung ke elemen HTML di panel Elements di DevTools juga dapat berguna.

Langkah 2: implementasi front-end

Kita mengubah insight ini menjadi draf pertama informasi yang ingin kami sediakan bagi DevTools melalui Protokol Chrome DevTools (CDP):

Di bawah ini 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. Hal ini ditulis dalam bahasa sederhana yang disebut PDL (protokol data language). 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 back-end 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 mana yang ingin kami sediakan, kami perlu mencari tahu tempat untuk mendapatkan informasi ini dari Chromium.

Langkah 3: deteksi masalah

Agar informasi tersedia untuk Protokol Chrome DevTools (CDP) dalam format yang dijelaskan di bagian terakhir, kita perlu menemukan tempat informasi sebenarnya tersedia di backend. Untungnya, kode CSP sudah memiliki botol-neck yang digunakan untuk mode laporan saja, yang dapat kita hubungkan 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 diperlukan perubahan besar pada backend agar instrumentasi kami dapat berfungsi.

Langkah 4: simpan dan tampilkan masalah

Detail kecil dapat terjadi karena kita juga ingin melaporkan masalah yang terjadi sebelum DevTools dibuka, mirip dengan cara penanganan pesan konsol. Ini berarti bahwa kita tidak melaporkan masalah secara langsung ke front-end, tetapi menggunakan penyimpanan yang diisi dengan masalah secara terpisah dari apakah DevTools terbuka atau tidak. Setelah DevTools dibuka (atau, dalam hal ini klien CDP lainnya terpasang), semua masalah yang telah dicatat sebelumnya dapat diputar ulang dari penyimpanan.

Ini adalah akhir dari pekerjaan {i>back-end<i}, dan sekarang kita perlu fokus pada cara memunculkan masalah di {i>front-end<i}.

Langkah 5: mendesain teks masalah

Merancang teks masalah adalah proses yang melibatkan beberapa tim selain tim kita sendiri, misalnya, kita sering mengandalkan wawasan dari tim yang mengimplementasikan fitur (dalam hal ini adalah tim CSP) dan tentu saja tim DevRel, yang mendesain bagaimana 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 yang dikhususkan untuk pelanggaran CSP.

Men-debug masalah Jenis Tepercaya

Menangani TT dalam skala besar bisa menjadi tantangan tanpa alat developer yang tepat.

Peningkatan pencetakan konsol

Saat menggunakan Objek Tepercaya, kami ingin menampilkan setidaknya jumlah informasi yang sama dengan jumlah informasi 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 pemanggilan .valueOf() pada objek secara default. Namun, dalam kasus Jenis Tepercaya, nilai yang ditampilkan tidak terlalu berguna. Sebagai gantinya, kita ingin menggunakan sesuatu yang serupa dengan yang Anda dapatkan saat memanggil .toString(). Untuk mencapai hal ini, kita perlu memodifikasi V8 dan Blink untuk memperkenalkan penanganan khusus untuk objek bertipe tepercaya.

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

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

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

Pelanggaran pelanggaran (dalam mode khusus laporan)

Saat ini, satu-satunya cara untuk melakukan debug pelanggaran TT adalah dengan menetapkan titik henti sementara pada pengecualian JS. Karena pelanggaran TT yang diterapkan akan memicu pengecualian, fitur ini bisa berguna. Namun, dalam skenario dunia nyata, Anda memerlukan kontrol yang lebih mendetail atas pelanggaran TT. Secara khusus, kami hanya ingin menghentikan pelanggaran TT (bukan pengecualian lainnya), menghentikan juga dalam mode laporan saja, 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 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 dilanggar. Backend, khususnya InspectorDOMDebuggerAgent, akan menyediakan "pemeriksaan", onTTViolation() yang akan dipanggil setiap kali pelanggaran TT terjadi. Kemudian, InspectorDOMDebuggerAgent akan memeriksa apakah pelanggaran tersebut akan memicu titik henti sementara, dan jika demikian, pesan akan dikirim ke frontend untuk menjeda eksekusi.

Apa yang telah dilakukan dan apa langkah selanjutnya?

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

Ke depannya, kami berencana menggunakan tab Issues untuk menampilkan masalah lainnya, yang akan memungkinkan penghapusan muatan alur pesan error yang tidak dapat dibaca di Konsol 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 mutakhir, dan menemukan masalah di situs Anda sebelum pengguna melakukannya.

Menghubungi tim Chrome DevTools

Gunakan opsi berikut untuk membahas fitur dan perubahan baru dalam postingan, atau hal lain yang terkait 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.
  • Tulis komentar di Video YouTube yang baru di DevTools atau Tips DevTools Video YouTube.