Topik temu duga representatif

Temu Duga Frontend: Bagaimanakah Anda Mencegah XSS dalam Aplikasi Web?

FrontendSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Sebuah aplikasi komuniti React memaparkan komen biasa sebagai teks biasa, manakala pengumuman moderator mungkin mengandungi set tag teks kaya (rich-text) dan pautan yang terhad. Semakan keselamatan mendapati data pengguna sampai ke dangerouslySetInnerHTML dan innerHTML, dan pertanyaan carian daripada location.search disisipkan ke dalam sepanduk hasil. Terangkan cara anda mengenal pasti risiko XSS tersimpan (stored), terpantul (reflected), dan berasaskan DOM (DOM-based), mereka bentuk semula setiap laluan rendering, menambah kawalan pertahanan berlapis (defense-in-depth), dan mengesahkan bahawa pembaikan tersebut berkesan.

Masalah dan Bila Ia Terpakai

Sebuah aplikasi komuniti React mempunyai tiga laluan rendering:

  • Komen biasa disimpan dalam pangkalan data dan harus dipaparkan tepat sebagai teks.
  • Pengumuman moderator boleh menggunakan kosa kata teks kaya yang terhad: perenggan, penekanan, senarai, dan pautan HTTPS.
  • Halaman carian membaca q daripada location.search dan memaparkan "Results for …" tanpa menunggu respons yang di-render oleh pelayan.

Satu semakan mendapati komen biasa dan pratonton pengumuman mengalir ke dalam dangerouslySetInnerHTML atau innerHTML. Sepanduk carian juga mencantumkan pertanyaan tersebut ke dalam rentetan HTML. Terangkan cara mencari setiap laluan source-to-sink, membezakan kitaran hayat serangan, memilih pengekodan atau sanitasi bagi setiap konteks, dan menambah kawalan yang mengurangkan kesan sekiranya terdapat sink yang terlepas pandang.

Jawapan asas merangkumi rendering pelayar dan pemilikan frontend. Pengesahan bahagian pelayan (server-side validation), pengesahan kebenaran (authorization), dan penyimpanan kandungan kekal sebagai sempadan yang diperlukan, tetapi ia tidak menjadikan sink DOM yang tidak selamat menjadi selamat. Ini merupakan soalan frontend kerana kemahiran yang menentukan ialah memahami penghuraian (parsing) pelayar, laluan keluar (escape hatches) rangka kerja, sink suntikan DOM, CSP, dan kontrak rendering yang boleh diuji.

Tersimpan (stored), terpantul (reflected), dan berasaskan DOM (DOM-based) adalah label yang berguna, tetapi ia menerangkan paksi yang berbeza. "Tersimpan" dan "terpantul" menerangkan cara data yang dikawal oleh penyerang sampai kepada mangsa. "Berasaskan DOM" menerangkan laluan pelaksanaan bahagian klien di mana JavaScript memindahkan data ke dalam sink suntikan. Muatan (payload) tersimpan atau terpantul masih boleh dilaksanakan melalui sink DOM, jadi label-label ini tidak semestinya saling eksklusif.

Perkara yang Dinilai oleh Penemu Duga

Isyarat pertama ialah sama ada calon melukis sempadan aliran data sebelum menyenaraikan pengepala keselamatan (security headers). Jawapan yang kukuh mengenal pasti punca seperti medan pangkalan data, parameter URL, serpihan (fragments), postMessage, dan respons pihak ketiga, kemudian mengenal pasti sink seperti innerHTML, outerHTML, insertAdjacentHTML, document.write, eval, dan pemasa berasaskan rentetan. Soalannya menjadi: bolehkah data yang dikawal oleh penyerang sampai kepada penghurai (parser) yang memperlakukannya sebagai markup, skrip, atau URL skrip?

Isyarat kedua ialah memilih pertahanan berdasarkan jenis data yang dimaksudkan. Komen biasa adalah teks, jadi ia harus sampai ke sink teks atau interpolasi JSX biasa. Pengumuman kaya sememangnya mengandungi HTML, jadi pengekodan entiti akan merosakkan ciri tersebut; ia memerlukan pensanitasi HTML yang diselenggara dengan dasar yang ketat sejurus sebelum sempadan rendering yang dipercayai. Nilai URL memerlukan pengesahan protokol dan destinasi selain daripada konteks output yang betul.

Isyarat ketiga ialah sama ada calon memahami batasan rangka kerja. React meloloskan (escapes) interpolasi rentetan biasa, tetapi dangerouslySetInnerHTML ialah escape hatch yang eksplisit. Rangka kerja tidak dapat menyelamatkan rentetan HTML mentah atau mengesahkan setiap URL javascript: atau data: yang dibekalkan kepada sifat yang berbahaya.

Isyarat terakhir ialah pengesahan berlapis. CSP boleh mengehadkan skrip mana yang dilaksanakan, dan Trusted Types boleh membuatkan sink suntikan terpilih menolak rentetan mentah. Kedua-dua kawalan ini tidak membaiki dasar pensanitasi yang terlalu longgar atau fungsi dasar yang tidak selamat. Jawapan yang kukuh membuang sink yang boleh dielakkan, memperketat sink yang tinggal, menggunakan kawalan pelayar, dan membuktikan hasilnya dengan semakan source-to-sink serta ujian muatan berniat jahat (hostile payload tests).

Soalan Penjelasan Sebelum Menjawab

  • Medan manakah yang merupakan teks dan medan manakah yang sememangnya mengandungi HTML? Jika setiap medan ialah teks, buang semua

rendering HTML mentah. Jika pengumuman memerlukan pemformatan, tentukan dasar tag, atribut, dan URL yang tepat sebelum memilih pensanitasi.

  • Siapa yang boleh mengarang pengumuman? Input khusus moderator mengurangkan pendedahan tetapi tidak menjadikannya dipercayai sepenuhnya. Sesi

moderator yang dicuri, import yang terjejas, migrasi, atau pepijat API masih boleh mengekalkan kandungan berniat jahat.

  • Adakah pautan pengumuman dibenarkan keluar dari tapak? Penyelesaian asas hanya membenarkan pautan HTTPS. Membenarkan

mel, protokol tersuai, imej, video, atau bingkai terbenam (embedded frames) memerlukan dasar yang lebih luas dan pengasingan tambahan.

  • Di manakah sanitasi dilakukan hari ini? Sanitasi semasa penulisan (write-time) boleh menolak input buruk lebih awal, tetapi

sempadan rendering masih memerlukan jaminan bahawa setiap nilai yang sampai ke sink HTML mentah telah disanitasi oleh dasar semasa.

  • Pelayar manakah yang mesti disokong? CSP berguna secara meluas. Sokongan dan tingkah laku pelancaran Trusted Types mesti

disemak terhadap matriks pelayar sebenar; klien yang tidak disokong masih bergantung pada sink yang selamat dan sanitasi.

  • Skrip pihak ketiga manakah yang diperlukan? Dasar skrip yang ketat lebih mudah apabila aplikasi mempunyai set skrip yang kecil dan

diaudit. Pengurus tag dan coretan sebaris (inline snippets) mengubah pelan migrasi CSP dan meluaskan impak sebarang XSS yang berjaya.

  • Apakah maksud "dibaiki" dari segi operasi? Jawapan harus merangkumi ujian regresi, pemantauan pelanggaran CSP,

kemas kini pensanitasi, pemilikan perubahan dasar, dan kaedah untuk mencari sink yang baru diperkenalkan.

Rangka Kerja Jawapan 30 Saat

"Saya akan menginventori punca yang tidak dipercayai dan sink yang boleh laku, kemudian membaiki setiap laluan mengikut jenis nilai yang dimaksudkan. Komen biasa dan pertanyaan carian adalah teks, jadi interpolasi React atau textContent harus me-rendernya tanpa penghuraian HTML. Ciri pengumuman benar-benar memerlukan HTML terhad, jadi saya akan menghantarnya melalui pensanitasi senarai benarkan (allowlist) yang diselenggara dan mendedahkan satu penyaji teks kaya yang ketat; pautan juga mendapat pengesahan protokol. Saya akan membuang panggilan innerHTML yang lain, menggunakan CSP berasaskan nonce atau hash dalam mod laporan sahaja (report-only) sebelum penguatkuasaan, dan menggunakan Trusted Types di mana matriks pelayar menyokongnya untuk menolak rentetan mentah pada sink DOM. Akhir sekali saya akan menguji muatan tersimpan, dipacu URL, markup salah bentuk, pengendali peristiwa, SVG, dan muatan URL skrip sambil memastikan pemformatan yang dibenarkan masih berfungsi."

Perbincangan Mendalam Langkah Demi Langkah

Langkah 1: Petakan setiap punca kepada setiap sink penghuraian

Mulakan dengan jadual aliran data yang kecil, bukan senarai rentetan muatan:

LaluanPunca dikawal penyerangSink semasaJenis dimaksudkanPerubahan diperlukan
Kad komenBadan komen pangkalan dataPenyaji HTML mentahTeksInterpolasi JSX atau textContent
PengumumanBadan pengumuman pangkalan dataPenyaji HTML mentahHTML TerhadSanitasi allowlist, kemudian satu sink yang disemak
Sepanduk carianlocation.searchPencantuman rentetan HTMLTekstextContent atau anak React berasaskan teks
Pautan pengumumanhref teks kayaAtribut mengandungi URLURL HTTPSHurai, sahkan protokol, dan sanitasi atribut

Semakan repositori harus mencari sink langsung dan pembungkus (wrappers) di sekelilingnya. Nama seperti safeHtml bukanlah bukti; jejak nilai tersebut kepada transformasi yang menciptanya. Periksa juga titik kemasukan tidak langsung: penyaji Markdown, editor teks kaya, komponen pratonton, mesej penyetempatan dengan markup, panggilan penghurai DOM, SVG, utiliti templat, coretan analitik, dan kod yang menyalin data URL atau mesej ke dalam halaman.

Kelaskan insiden selepas laluannya diketahui:

  • Komen berniat jahat yang dikekalkan dalam pangkalan data dan dipaparkan kepada pengguna lain mempunyai kitaran hayat tersimpan (stored).
  • Parameter permintaan yang disalin ke dalam respons pelayan serta-merta mempunyai kitaran hayat terpantul (reflected).
  • Pertanyaan atau serpihan yang dibaca oleh JavaScript klien dan dihantar ke innerHTML mempunyai laluan pelaksanaan berasaskan DOM.

Pengelasan ini membantu tindak balas insiden, tetapi keputusan pemulihan masih datang daripada punca, konteks output, dan sink.

Langkah 2: Pastikan teks kekal sebagai teks

Komen biasa dan label carian tidak memerlukan markup. Gunakan anak React biasa:

tsx
function CommentBody({ body }: { body: string }) {
  return <p>{body}</p>
}

function SearchSummary({ query }: { query: string }) {
  return <p>Results for “{query}”</p>
}

Di luar React, gunakan sink teks:

typescript
summaryNode.textContent = query

Pelayar kini menerima data sebagai teks dan bukannya menghuraikannya semula sebagai HTML. Jangan "bersihkan" rentetan dengan ungkapan nuaian (regular expression) dan terus menetapkannya kepada innerHTML; penghuraian HTML mempunyai terlalu banyak elemen, atribut, pengekodan, dan peraturan pemulihan input salah bentuk untuk pendekatan itu dianggap boleh dipercayai.

Konteks masih penting. Keselamatan teks tidak secara automatik menjadikan sesuatu nilai itu selamat dalam pengendali peristiwa, blok skrip, peraturan CSS, atau URL. Elakkan meletakkan nilai yang tidak dipercayai dalam konteks yang boleh dilaksanakan. Apabila sesuatu nilai berada dalam atribut yang selamat, kodkan nama atribut secara kekal (hardcode) dan gunakan sifat rangka kerja atau setAttribute hanya selepas menggunakan pengesahan yang diperlukan oleh atribut tersebut.

Langkah 3: Asingkan satu-satunya ciri yang memerlukan HTML

Keperluan pengumuman tidak boleh menggunakan teks biasa kerana pemformatan terpilih mesti dikekalkan. Tentukan dasar sebelum pelaksanaan:

  • Tag yang dibenarkan: perenggan, penekanan kuat, penekanan, senarai tidak tertib dan tertib, item senarai, dan sauh (anchors).
  • Atribut yang dibenarkan: hanya href, title, dan atribut pautan yang ditambah oleh penyaji.
  • Protokol pautan yang dibenarkan dalam senario asas: HTTPS.
  • Kandungan yang tidak dibenarkan: skrip, atribut pengendali peristiwa, gaya sebaris, bingkai, borang, SVG, dan media sewenang-wenangnya.

Kemudian pusatkan sink HTML mentah:

tsx
function RichAnnouncement({ dirtyHtml }: { dirtyHtml: string }) {
  const cleanHtml = sanitizeRichText(dirtyHtml, RICH_TEXT_POLICY)
  return <div dangerouslySetInnerHTML={{ __html: cleanHtml }} />
}

sanitizeRichText mewakili pensanitasi berasaskan penghurai yang diselenggara dan dikonfigurasikan dengan dasar tersebut. OWASP mengesyorkan DOMPurify sebagai salah satu pilihan. Sifat keselamatan datang daripada pensanitasi dan konfigurasinya, bukan daripada nama pemboleh ubah atau jenis TypeScript.

Sanitasi sejurus sebelum sempadan rendering yang disemak. Sanitasi semasa penulisan boleh menyediakan semakan tambahan, tetapi bergantung padanya sahaja meninggalkan jurang untuk baris lama, import, migrasi, API alternatif, dan perubahan dasar. Jika sistem menyimpan output yang disanitasi untuk prestasi, rekodkan versi pensanitasi dan dasar supaya kandungan yang lebih lama boleh diproses semula selepas kemas kini keselamatan.

Jangan ubah suai HTML dengan pencantuman rentetan selepas sanitasi. Menambah pautan, sorotan (highlight), atau pembungkus dengan mengedit rentetan yang disanitasi boleh memperkenalkan semula binaan yang tidak selamat. Bina UI yang dipercayai di luar kawasan HTML mentah, atau hantar kandungan akhir melalui pensanitasi sekali lagi.

Langkah 4: Perlakukan URL sebagai input berstruktur

Sanitasi HTML mesti merangkumi atribut pautan, tetapi dasar produk juga harus jelas. Hurai calon URL terhadap pangkalan (base) yang diketahui, periksa protokol yang terhasil, dan hanya terima protokol yang diperlukan oleh ciri tersebut. Dalam senario ini, hanya HTTPS yang dibenarkan.

Mengekodkan URL yang berbahaya tidak menjadikan skimnya boleh diterima. Sesuatu nilai boleh dikodkan dengan betul untuk href namun masih menggunakan protokol yang membawa skrip. Keputusan URL dan konteks atribut HTML ialah semakan yang berasingan. Bagi pautan luaran yang dibuka dalam tab baharu, tambah atribut hubungan yang sesuai melalui penyaji; ini mengehadkan akses opener tetapi tidak menggantikan pencegahan XSS.

Elakkan URL skrip yang dikawal pengguna sepenuhnya. eval, Function, setTimeout berasaskan rentetan, setInterval berasaskan rentetan, dan pembinaan sumber skrip dinamik tidak seharusnya menerima nilai yang tidak dipercayai. Laluan ini memerlukan penyingkiran atau pemetaan pratakrif yang kecil, bukan pensanitasi tujuan umum.

Langkah 5: Tambah CSP sebagai barisan pertahanan kedua

CSP boleh menyekat pelaksanaan skrip jika terdapat sink yang terlepas pandang. Utamakan pengepala respons dan reka dasar di sekitar sumber sebenar aplikasi. Arah yang dipermudahkan ialah:

http
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{per-response-random-value}';
  object-src 'none';
  base-uri 'none'

Nonce mestilah tidak dapat diramalkan dan unik bagi setiap respons, dan hanya skrip yang diluluskan menerimanya. Dasar berasaskan hash boleh disesuaikan untuk kandungan sebaris yang stabil. Elakkan melemahkan dasar dengan senarai hos yang luas atau unsafe-inline semata-mata untuk mendiamkan pelanggaran.

Mulakan dengan Content-Security-Policy-Report-Only, kumpulkan pelanggaran, buang kod sebaris yang tidak dijangka, dan kemudian kuat kuasakan. Mod laporan sahaja menyediakan bukti penggunaan tetapi tidak menyekat apa-apa. CSP kekal sebagai pertahanan berlapis: skrip yang dibenarkan masih mempunyai keistimewaan halaman, sokongan pelayar berbeza mengikut ciri, dan dasar yang terlalu longgar boleh menyebabkan eksploitasi asal masih berfungsi.

Langkah 6: Gunakan Trusted Types untuk mengekang suntikan DOM

Di mana ia disokong, tambah arahan CSP:

http
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app-rich-text

Penguatkuasaan membuatkan sink suntikan DOM yang dilindungi menolak rentetan biasa. Aplikasi hanya mencipta dasar yang dinamakan, dan dasar tersebut mewakilkan penciptaan HTML kepada pensanitasi yang diluluskan. Ini mengubah penetapan tidak selamat yang senyap menjadi pengecualian yang kelihatan dan menjadikan sink rentetan mentah baharu lebih mudah dikesan dalam ujian dan pemantauan.

Dasar yang mengembalikan input tanpa perubahan akan menggagalkan kawalan ini. Dasar lalai (default policy) yang luas juga boleh menyembunyikan laluan legasi dengan menukar setiap rentetan secara automatik. Gunakan dasar lalai buat sementara waktu semasa migrasi untuk diagnostik, kemudian alihkan pemanggil kepada nilai dipercayai yang eksplisit dan buang sink yang boleh dielakkan.

Trusted Types tidak merangkumi setiap cara yang mungkin untuk melaksanakan kod, dan pelayar yang lebih lama mungkin kekurangan penguatkuasaan. Asas utamanya tetap merupakan rendering yang selamat, sanitasi yang ketat, pengesahan URL, dan penyingkiran API rentetan yang boleh laku.

Langkah 7: Kurangkan impak di luar fungsi rendering

Kuki sesi biasanya harus menggunakan HttpOnly, Secure, dan dasar SameSite yang sesuai. HttpOnly boleh menghalang JavaScript yang disuntik daripada membaca kuki tersebut secara langsung, tetapi XSS yang aktif masih boleh menghantar permintaan sebagai pengguna atau membaca data yang tersedia untuk halaman. Atribut kuki mengurangkan impak; ia tidak menutup laluan suntikan.

Pengesahan kebenaran pelayan mesti melindungi setiap tindakan sensitif walaupun frontend menyembunyikan sesuatu kawalan. Sanitasi atau sahkan di sempadan pelayan di mana sesuai, dan pastikan input penyerang yang disimpan dilabelkan sebagai tidak dipercayai. Skrip pihak ketiga dilaksanakan dengan keistimewaan halaman, jadi kurangkan bilangannya, skopkannya kepada laluan yang diperlukan, audit kemas kini, dan masukkannya dalam reka bentuk CSP.

Langkah 8: Sahkan kedua-dua keselamatan dan pemformatan yang dimaksudkan

Bina korpus ujian yang merangkumi laluan penghurai yang berbeza:

text
<img src=x onerror=alert(1)>
<a href="javascript:alert(1)">open</a>
<svg onload=alert(1)></svg>
"><script>alert(1)</script>
malformed tags and mixed character encodings

Gunakan panggilan balik (callbacks) ujian lengai dalam persekitaran ujian yang terpencil dan bukannya tingkah laku pemusnah yang sebenar. Sahkan:

  1. Komen biasa memaparkan setiap aksara dan tidak mencipta elemen.
  2. Parameter carian kekal sebagai teks selepas navigasi biasa, URL terkod, sejarah pelayar, dan penghidratan (hydration).
  3. Tag pengumuman yang dibenarkan kekal sementara skrip, pengendali peristiwa, gaya, SVG, bingkai, dan URL yang tidak selamat

dibuang.

  1. Output pensanitasi tidak diubah sebelum sampai ke sink HTML mentah.
  2. Telemetri mod laporan sahaja CSP difahami, kemudian penguatkuasaan menyekat sink ujian yang sengaja diperkenalkan.
  3. Penguatkuasaan Trusted Types mencetuskan ralat (throws) pada rentetan mentah dan hanya menerima output dasar disanitasi yang diluluskan.
  4. Lekapan (fixtures) teks kaya sedia ada, pautan, struktur pembaca skrin, dan tingkah laku salin-tampal masih berfungsi.

Tambah semakan statik untuk sink baharu, ujian unit untuk dasar pensanitasi, ujian integrasi untuk setiap laluan rendering, dan ujian pelayar terhadap matriks yang disokong. Pastikan pensanitasi sentiasa ditampal dan jalankan semula korpus berniat jahat apabila pelayar, rangka kerja, pensanitasi, editor, atau dasar berubah.

Contoh Jawapan Berkualiti Tinggi

"Mula-mula, saya akan mengenal pasti punca yang tidak dipercayai dan API pelayar yang menghuraikannya. Badan komen pangkalan data, HTML pengumuman, dan q daripada location.search ialah punca. innerHTML, dangerouslySetInnerHTML, dan sebarang pembina skrip atau URL skrip ialah sink yang akan saya jejak.

Komen dan sepanduk carian ialah ciri teks. Saya akan me-rendernya sebagai anak React atau menetapkan textContent, supaya pelayar tidak mentafsir aksaranya sebagai markup. Pengumuman mempunyai kontrak yang berbeza kerana ia membenarkan HTML terhad. Saya akan menentukan allowlist kecil untuk perenggan, penekanan, senarai, dan pautan HTTPS, menghantar nilai akhir melalui pensanitasi berasaskan penghurai yang diselenggara, dan mengekalkan satu komponen HTML mentah yang disemak. Pensanitasi juga akan membuang pengendali peristiwa, gaya, SVG, bingkai, dan skim URL yang tidak selamat. Tiada kod yang akan mencantumkan markup selepas langkah tersebut.

Saya akan menerangkan komen berniat jahat yang disimpan sebagai kitaran hayat tersimpan dan laluan pertanyaan carian sebagai berasaskan DOM. Jika pelayan menyalin nilai permintaan ke dalam respons HTML serta-mertanya, itu adalah terpantul. Label-label ini membantu mencari pendedahan, manakala pembaikan masih datang daripada konteks output dan sink.

Untuk pertahanan berlapis, saya akan melancarkan CSP berasaskan nonce atau hash melalui mod laporan sahaja, membuang pelanggaran, kemudian menguatkuasakannya. Di mana sokongan pelayar kami membenarkannya, saya akan mewajibkan Trusted Types untuk sink skrip dan hanya membenarkan dasar dinamakan yang memanggil pensanitasi yang diluluskan. Saya tidak akan menggunakan CSP, kuki HttpOnly, atau dasar Trusted Types yang mengembalikan input tanpa perubahan sebagai pembaikan utama.

Pengesahan saya akan merangkumi muatan tersimpan, muatan URL, markup salah bentuk, atribut peristiwa, SVG, dan URL skrip. Saya akan mengesahkan bahawa laluan teks tidak mencipta elemen, pemformatan yang dibenarkan kekal, kandungan yang tidak dibenarkan dibuang, penetapan rentetan mentah gagal di bawah Trusted Types, dan CSP yang dikuatkuasakan menyekat sink ujian yang sengaja diperkenalkan. Saya juga akan memastikan pensanitasi sentiasa dikemas kini dan menjadikan sink suntikan baharu sebagai titik semakan dalam semakan kod dan analisis statik."

Kesilapan Biasa

  • Meloloskan setiap nilai dengan cara yang sama → pelayar menghuraikan HTML, atribut, URL, CSS, dan JavaScript di bawah

peraturan yang berbeza → jauhkan data daripada konteks yang boleh dilaksanakan dan gunakan pertahanan yang diperlukan oleh sink yang tepat.

  • Menghantar teks biasa melalui innerHTML selepas membuang tag skrip → atribut peristiwa, markup salah bentuk,

SVG, skim URL, dan tingkah laku penghurai masih kekal → gantikan sink dengan rendering teks JSX atau textContent.

  • Mengekod teks kaya → markup muncul secara literal dan ciri tersebut rosak → **gunakan pensanitasi HTML

yang diselenggara dengan allowlist yang ketat apabila HTML ialah keperluan produk yang eksplisit.**

  • Mempercayai kandungan khusus moderator → akaun yang terjejas, import, migrasi, dan kecacatan API boleh mengekalkan

markup berniat jahat → perlakukan kandungan yang disimpan sebagai tidak dipercayai pada sempadan rendering.

  • Menyapubersih dan kemudian mencantumkan lebih banyak HTML → mutasi terkemudian boleh mencipta semula binaan yang boleh dilaksanakan →

jadikan sanitasi sebagai transformasi terakhir sebelum sink yang disemak.

  • Mengesahkan href hanya dengan pengekodan HTML → nilai yang dikodkan masih boleh membawa protokol yang tidak boleh diterima →

hurai URL dan hanya benarkan skim dan destinasi yang diperlukan.

  • Menganggap pelolosan automatik React sebagai universal → escape hatches dan API DOM langsung memintas interpolasi rentetan

biasa → inventori setiap laluan HTML mentah dan rentetan yang boleh dilaksanakan.

  • Bergantung pada CSP sahaja → dasar yang lemah, skrip yang dibenarkan, atau ciri yang tidak disokong boleh menyebabkan sink

masih boleh dieksploitasi → buang sink yang tidak selamat terlebih dahulu dan gunakan CSP sebagai halangan tambahan.

  • Mencipta dasar Trusted Types yang mengembalikan inputnya → pelayar melihat objek yang dipercayai tanpa

transformasi yang boleh dipercayai → hadkan nama dasar dan wakilkan kepada pensanitasi yang disemak.

  • Hanya menyemak sama ada muatan alert telah berhenti → satu muatan tidak merangkumi skim URL, markup salah bentuk,

elemen alternatif, atau regresi dalam pemformatan yang dibenarkan → selenggara korpus berniat jahat yang pelbagai dan lekapan teks kaya yang positif.

Soalan Susulan

Susulan 1: Bagaimanakah anda memindahkan aplikasi legasi dengan beratus-ratus penetapan innerHTML?

Inventori sink dan nilaikan mengikut punca tidak dipercayai yang boleh dicapai, pendedahan pengguna, dan keistimewaan. Gantikan laluan khusus teks terlebih dahulu. Perkenalkan satu sempadan teks kaya yang disemak untuk HTML sah yang selebihnya. Gunakan CSP dan Trusted Types dalam mod laporan sahaja atau diagnostik untuk mendedahkan laluan masa jalan (runtime) yang terlepas daripada carian statik. Dasar lalai Trusted Types sementara boleh merekodkan panggilan legasi, tetapi ia tidak sepatutnya meluluskan rentetan yang tidak berubah secara senyap; alihkan pemanggil kepada dasar eksplisit dan buang laluan keserasian sementara.

Susulan 2: Apakah yang berubah jika pengumuman mesti membenarkan imej dan video terbenam?

Kontrak kepercayaan berkembang. Tentukan asal (origins) imej yang dibenarkan, skim URL, dimensi, tingkah laku pemuatan, dan peraturan privasi. Memproksi imej boleh mengurangkan permintaan pihak ketiga secara langsung. Video terbenam harus menggunakan allowlist penyedia yang kecil dan bingkai terpencil (sandboxed frame) dengan keupayaan yang diperlukan sahaja. Dasar pensanitasi, arahan CSP, tingkah laku keizinan, dan korpus ujian semuanya berubah. Bingkai, gaya, dan HTML penyedia sewenang-wenangnya tidak seharusnya memasuki penyaji pengumuman sedia ada.

Susulan 3: Bagaimana jika CSP yang ketat merosakkan skrip analitik dan pengurus tag?

Jalankan dasar yang dicadangkan dalam mod laporan sahaja dan kelaskan setiap pelanggaran mengikut pemilik perniagaan dan tujuan skrip. Buang skrip yang tidak digunakan, gantikan coretan sebaris dengan modul luaran yang diluluskan, dan berikan skrip yang diperlukan nonce bagi setiap respons atau hash yang stabil mengikut kesesuaian. Kad liar (wildcard) yang luas atau unsafe-inline memulihkan keserasian dengan mengorbankan sebahagian besar sempadan keselamatan. Jika pengurus tag boleh menyuntik skrip sewenang-wenangnya, dokumentasikan bahawa ia kekal sebagai laluan kod berkeistimewaan dan hadkan pihak yang boleh menerbitkan melaluinya.

Susulan 4: Pelayan telah pun mensanitasi pengumuman. Mengapa perlu mengekalkan sempadan frontend?

Komponen HTML mentah memerlukan kontrak input yang boleh disahkan tanpa mengira tempat transformasi dijalankan. API alternatif, baris lama, import, entri cache, migrasi, atau dasar yang berubah boleh memintas anggapan semasa penulisan. Kapsulkan sink supaya pemanggil hanya boleh menyediakan output daripada pensanitasi semasa, uji kontrak tersebut, dan versikan kandungan disanitasi yang disimpan jika ia digunakan semula. Semakan pelayan mengurangkan kemasukan data buruk ke dalam sistem; sempadan rendering menghalang nilai yang tidak disahkan daripada sampai ke penghurai.

Susulan 5: Bagaimanakah anda menyiasat laporan XSS pengeluaran?

Kekalkan URL yang dilaporkan, pengecam kandungan, pelayar, laporan CSP, dan versi penggunaan yang berkaitan tanpa melaksanakan muatan tersebut dalam akaun biasa. Hasilkan semula dalam persekitaran terpencil, jejak laluan source-to-sink yang tepat, dan tentukan sama ada muatan itu disimpan, dipacu permintaan, atau dibekalkan oleh pihak ketiga. Buang atau nyahdayakan laluan rendering yang terdedah, batalkan kandungan berniat jahat yang disimpan jika perlu, putarkan kelayakan yang terdedah, semak tindakan sensitif yang dilakukan semasa tempoh pendedahan, kemudian tambah kelas muatan tersebut ke dalam korpus regresi sebelum memulihkan ciri tersebut.

Sumber awam

Soalan berkaitan