Gesaan dan senario yang berkenaan
Hos berjalan di https://app.example.com dan membenamkan iframe pembayaran daripada https://pay.example.net. Selepas widget bersedia, hos menghantar lokal (locale), tema, dan rujukan sesi pembayaran jangka pendek. Iframe melaporkan ready, perubahan ketinggian, pembatalan pengguna, dan penyiapan aliran pembayaran. Halaman mungkin mengandungi beberapa iframe dengan asal yang sama (same-origin), dan widget mungkin mengubah hala (redirect) atau dicipta semula semasa pemuatan.
Reka protokol dwiarah postMessage dan pelaksanaan frontend. Rangkumi tetingkap destinasi, identiti penerima, bentuk mesej, pemasaan pengawalan (initialization timing), pendua dan penyusunan semula, navigasi, pembersihan (cleanup), serta ujian keselamatan. Mesej penyiapan hanya menggesa UI untuk disegarkan semula; pelayan hos mesti mengesahkan keadaan pembayaran muktamad dengan sistem pembayaran yang berwibawa.
Soalan ini sesuai untuk peranan frontend kanan, platform Web, seni bina frontend, dan keselamatan aplikasi. Kemahiran terasnya ialah dasar asal sama (same-origin policy) pelayar, pemesejan rentas dokumen, sempadan kepercayaan klien, dan reka bentuk protokol tak segerak (asynchronous), jadi kategorinya ialah frontend. CORS mengawal sama ada skrip pelayar boleh membaca respons rangkaian rentas asal. Ia tidak menggantikan kekangan destinasi postMessage atau pengesahan pendengar mesej (message listener).
Perkara yang dinilai oleh penemu duga
Isyarat pertama ialah sama ada calon melindungi kedua-dua penghantar dan penerima. Penghantar membekalkan targetOrigin yang tepat supaya data tidak dihantar selepas tetingkap sasaran bernavigasi ke asal yang lain. Penerima menyemak event.origin pada setiap mesej dan, apabila ia mempunyai rujukan tetingkap yang dijangka, menyemak event.source. Melaksanakan satu bahagian sahaja masih meninggalkan laluan pendedahan atau pemalsuan.
Isyarat kedua ialah sama ada calon menganggap pemesejan sebagai titik masuk awam dengan input yang tidak diketahui. Lulus semakan asal hanya mengenal pasti asal tempat kod dijalankan. Ia tidak membuktikan bentuk muatan (payload shape), dan ia juga tidak menghalang XSS atau kod yang rosak pada asal yang dipercayai daripada menghantar arahan berbahaya. Jawapan yang kukuh mentakrifkan sampul (envelope) berversi, jenis mesej yang dibenarkan, kekangan medan, had saiz, dan peralihan keadaan sebelum menyempitkan event.data daripada unknown.
Isyarat ketiga ialah pengendalian pemasaan tak segerak. Mesej pengawalan yang dihantar sebelum iframe mendaftarkan pendengarnya akan hilang begitu sahaja tanpa sebarang amaran. Aliran yang boleh dipercayai mendaftarkan pendengar induk terlebih dahulu, memuatkan iframe, membiarkan anak mengumumkan ready, dan menghantar init hanya selepas pengesahan. ID mesej, ID saluran, tamat masa (timeouts), dan peralihan keadaan idempoten mengendalikan percubaan semula, pendua, dan mesej yang lewat.
Akhir sekali, penemu duga mencari sempadan kepercayaan sebelah pelayan. Mesej complete daripada iframe yang disahkan masih bukan bukti pembayaran. Frontend harus menggunakan rujukan hasil tanpa butiran sensitif untuk menanyakan pelayan hos. CSP, frame-src, frame-ancestors, dan kebenaran minimum sandbox mengurangkan pendedahan, tetapi ia tidak menggantikan identiti peringkat mesej dan pengesahan data.
Soalan untuk dijelaskan terlebih dahulu
- Adakah kedua-dua asal ditetapkan (fixed)? Dua asal yang tetap membolehkan perbandingan tepat. Jika hos menyokong domain tersuai pelanggan, halaman pembayaran mesti mendapatkan asal induk yang dibenarkan untuk sesi ini daripada pelayannya. Ia tidak boleh mempercayai mana-mana
event.originyang muncul dahulu. - Apakah data sensitif yang merentasi saluran? Tema dan ketinggian berisiko rendah. Kredensial pembayaran, data peribadi, atau token pembawa yang boleh diguna semula tidak boleh melalui antara muka gaya siaran (broadcast). Jika keupayaan mesti melintas, gunakan rujukan jangka pendek, terikat pada audiens, boleh dibatalkan, dan mempunyai keistimewaan paling rendah.
- Siapa yang boleh membenamkan halaman pembayaran? Halaman pembayaran harus menyekat pembenam dengan
frame-ancestors. Sekiranya terdapat banyak penyewa yang sah, jana dasar yang tepat di sebelah pelayan atau gunakan titik masuk pembenaman yang terkawal daripada membenarkan setiap tapak. - Berapa banyak iframe asal sama yang boleh wujud pada satu halaman? Dengan satu iframe, asal ditambah dengan
contentWindowyang dijangka dapat mengesan rakan sebaya (peer). Pelbagai contoh memerlukan rujukan tetingkap berasingan dan keadaan protokol yang terikat saluran; pengendali siaran khusus asal sahaja tidak mencukupi. - Mesej manakah yang mencetuskan tindakan sensitif?
resizeboleh menjejaskan reka letak secara langsung.complete, bayaran balik, penyerahan pesanan, atau perubahan akaun memerlukan kebenaran pelayan dan carian keadaan yang berwibawa. Mesej membawa isyarat, bukan kuasa perniagaan. - Apakah yang boleh dicuba semula selepas kegagalan?
readydaninitboleh dicuba semula secara idempoten. Mesej yang dihantar semula tidak boleh melaksanakan penyerahan pembayaran dua kali. Tentukan siapa yang memiliki ID mesej, keadaan terminal, dan kunci keidempotenan pelayan.
Rangka jawapan 30 saat
“Saya akan menganggap postMessage sebagai API tak segerak merentasi sempadan kepercayaan. Induk mendaftarkan pendengarnya dan menyimpan contentWindow iframe sebelum anak menghantar ready. Untuk setiap mesej, induk mengesahkan asal yang tepat, sumber yang dijangka, dan skema masa jalan (runtime schema), kemudian membalas dengan init menggunakan targetOrigin yang tepat. Protokol ini mempunyai versi, ID saluran, dan ID mesej, manakala mesin keadaan menolak mesej sebelum jabat tangan, pendua, penyusunan semula, dan perubahan selepas keadaan terminal. complete hanya menyebabkan hos menanyakan status pembayaran yang berwibawa melalui pelayannya. Saya akan menguji asal berniat jahat, iframe asal sama yang salah, data yang salah bentuk (malformed), main semula, dan perlumbaan navigasi, kemudian mengurangkan pendedahan dengan CSP dan kebenaran iframe minimum.”
Kupasan mendalam langkah demi langkah
Langkah satu: petakan sempadan kepercayaan dalam kedua-dua arah
Sebelum induk menghantar, ia mempunyai dua persoalan: sama ada rujukan Window miliknya tergolong dalam iframe yang dimaksudkan, dan sama ada dokumen sasaran masih mempunyai asal yang dijangka apabila panggilan itu dijalankan. targetOrigin menangani persoalan kedua. Jika sasaran bernavigasi ke tempat lain, pelayar akan membuang mesej tersebut. Menggunakan "*" menghapuskan kekangan penerima tersebut.
Penerimaan juga mempunyai dua soalan bebas: asal yang mana menghantar mesej, dan tetingkap yang mana pada asal tersebut menghantarnya. Mana-mana halaman yang memperoleh rujukan kepada tetingkap semasa boleh cuba menghantar mesej. Iframe yang berbeza pada asal yang dipercayai yang sama juga boleh mengeluarkan peristiwa dengan nama yang sama. Oleh itu, penerima memeriksa sekurang-kurangnya:
event.originsama tepat dengan skema penuh, hos, dan port;event.sourceialah rujukan yang sama dengancontentWindowiframe yang disimpan;event.datasepadan dengan bentuk mesej yang dibenarkan oleh keadaan protokol semasa.
Jangan gunakan pembendungan akhiran (suffix containment), serpihan regex, atau indexOf untuk menerima asal. https://pay.example.net.attacker.test boleh melepasi semakan substring yang longgar. Jangan tambah event.origin pada senarai benarkan secara dinamik juga; tindakan itu mengubah cubaan pertama penyerang menjadi pendaftaran.
Langkah dua: tentukan protokol mesej yang kecil dan eksplisit
Wakilkan mesej sebagai kesatuan yang didiskriminasikan (discriminated union), bukan objek sewenang-wenangnya atau arahan rentetan. Protokol padat boleh mengandungi:
| Medan | Tujuan | Pengesahan |
|---|---|---|
v | Versi protokol | Terima hanya versi integer yang disokong |
type | Jenis mesej | Enum tetap; jangan sesekali menggunakan nama fungsi dinamik |
messageId | Nyahduplikasi dan korelasi audit | Tidak kosong, panjang terikat, unik dalam tetingkap semasa |
channelId | Ikat satu jabat tangan yang berjaya | Dicipta oleh induk selepas ready; setiap mesej kemudian mesti sepadan |
| Medan perniagaan | Data minimum yang diperlukan oleh mesej tersebut | Sahkan setiap jenis, julat, dan panjang |
ready tidak mempunyai channelId sebelum saluran wujud. Induk menerimanya melalui asal dan sumber yang telah disahkan, mencipta channelId rawak, dan menghantar init. Mesej resize, cancel, dan complete yang menyusul mesti menggemakan ID saluran tersebut. Saluran ini memisahkan sesi lama dan mesej yang lewat dalam tetingkap yang sama. Ia tidak menggantikan asal, sumber, atau kebenaran pelayan.
Mulakan penghuraian penerima daripada unknown. Ini ialah contoh induk TypeScript yang dipermudahkan. parseWidgetMessage mewakili pengesahan masa jalan yang ketat, bukan penegasan jenis (type assertion):
const WIDGET_ORIGIN = "https://pay.example.net"
const frame = document.querySelector<HTMLIFrameElement>("#payment-widget")
if (!frame?.contentWindow) {
throw new Error("Payment iframe is unavailable")
}
const widgetWindow = frame.contentWindow
let channelId: string | null = null
const seenMessageIds = new Set<string>()
let state: "loading" | "active" | "completed" | "closed" = "loading"
window.addEventListener("message", onWidgetMessage)
frame.src = "https://pay.example.net/embed"
function onWidgetMessage(event: MessageEvent<unknown>) {
if (event.origin !== WIDGET_ORIGIN) return
if (event.source !== widgetWindow) return
const message = parseWidgetMessage(event.data)
if (!message || seenMessageIds.has(message.messageId)) return
seenMessageIds.add(message.messageId)
if (message.type === "ready") {
if (state !== "loading") return
channelId = crypto.randomUUID()
widgetWindow.postMessage(
{
v: 1,
type: "init",
messageId: crypto.randomUUID(),
channelId,
locale: "zh-CN",
theme: "system",
checkoutSessionRef: "short-lived-opaque-reference",
},
WIDGET_ORIGIN,
)
state = "active"
return
}
if (state !== "active" || channelId === null || message.channelId !== channelId) return
if (message.type === "resize") {
frame.style.height = `${Math.min(Math.max(message.height, 240), 900)}px`
}
if (message.type === "complete") {
state = "completed"
void refreshAuthoritativePaymentStatus(message.resultRef)
}
}Penghurai sebenar juga menolak jenis berbahaya yang tidak dikenali, rentetan bersaiz lebih, nombor tidak terhingga, dan gabungan keadaan yang tidak dibenarkan. Jangan gunakan as WidgetMessage untuk melangkau semakan masa jalan. Pengklonan berstruktur (structured clone) boleh membawa objek; ia tidak membuktikan bahawa objek memenuhi protokol aplikasi.
Anak menggunakan peraturan yang sama dalam arah yang bertentangan. Ia hanya menerima asal hos yang dikonfigurasikan lebih awal atau terikat oleh sesi sebelah pelayan, memerlukan event.source === window.parent, menyimpan ID saluran hanya selepas mengesahkan skema init, dan sentiasa membalas dengan asal hos yang tepat. Kedua-dua pihak tidak boleh mengabaikan pengesahan semata-mata kerana ia hanya menjangkakan satu rakan sejawatan.
Langkah tiga: hapuskan kekaburan pemasaan dengan jabat tangan dan mesin keadaan
Piawaian HTML memberi amaran bahawa dokumen anak yang baru dinavigasi mungkin belum memasang pendengar mesejnya lagi. Mesej induk yang dihantar pada waktu itu tidak menunggu dalam barisan untuk anak menjadi sedia. Induk memasang pendengarnya sebelum menetapkan atau mengesahkan URL iframe. Anak memasang pendengarnya dan mengumumkan ready. Induk menghantar pengawalan sensitif hanya selepas ready melepasi semakan asal, sumber, dan skema.
Mesin keadaan menjadikan tindakan yang dibenarkan eksplisit:
| Keadaan semasa | Mesej yang diterima | Keadaan selepas itu |
|---|---|---|
loading | ready | active |
active | resize, cancel, complete | Sama, closed, atau completed |
completed | Tiada mesej perniagaan; pengesahan baca sahaja pilihan | Kekal completed |
closed | Tiada | Kekal closed |
Induk boleh meletakkan had masa pada jabat tangan. Apabila tamat masa ia menunjukkan ralat yang boleh dicuba semula dan memusnahkan iframe lama. Mencipta semula iframe memerlukan ID saluran baharu, set nyahduplikasi kosong, rujukan tetingkap jangkaan yang dikemas kini, dan pembuangan pendengar lama. Menggunakan semula saluran lama akan membenarkan mesej lewat daripada halaman sebelumnya memasuki sesi baharu.
Langkah empat: pisahkan mesej pendua, tindakan perniagaan pendua, dan fakta pelayan
Penghantaran mesej dan pelaksanaan perniagaan memerlukan dua lapisan keidempotenan. Frontend menggunakan messageId untuk mengabaikan mesej UI pendua dan mesin keadaan untuk menolak perubahan selepas keadaan terminal. Pelayan masih memerlukan kunci keidempotenan pesanan atau percubaan pembayaran untuk mengelakkan caj pendua, kerana penyegaran semula, percubaan semula rangkaian, dan beberapa tab boleh memintas set frontend.
complete hanya bermakna bahawa tetingkap yang dipercayai mendakwa aliran telah selesai. Induk menghantar resultRef ke pelayannya sendiri. Pelayan mengesahkan pengguna semasa, pemilikan pesanan, amaun, dan keadaan penyedia pembayaran yang berwibawa sebelum mengembalikan hasil yang boleh dipaparkan. Walaupun XSS mengawal skrip pada asal iframe pembayaran, complete yang dipalsukan tidak boleh menandakan pesanan telah dibayar secara langsung.
Log mesej hanya mengandungi versi protokol, jenis, cincangan saluran, hasil, dan sebab penolakan. Ia tidak mengandungi kredensial pembayaran, data peribadi penuh, atau token yang boleh diguna semula. Hadkan set nyahduplikasi atau musnahkannya bersama-sama saluran supaya serangan atau halaman yang berjalan lama tidak dapat meningkatkan penggunaan memori selama-lamanya.
Langkah lima: kendalikan navigasi, pelbagai contoh (multiple instances), dan asal yang dikongsi
event.origin ialah asal penghantar apabila ia memanggil postMessage. Ia tidak menjamin bahawa tetingkap penghantar mempunyai asal semasa atau masa hadapan yang sama. Sahkan semula setiap mesej daripada mempercayai tetingkap tersebut selama-lamanya selepas satu jabat tangan. Jika iframe sasaran bernavigasi ke asal penyerang, targetOrigin yang tepat akan menghentikan mesej induk seterusnya, dan penerima induk menolak mesej baharu kerana asalnya berbeza.
Jika iframe bernavigasi ke aplikasi yang berbeza pada asal yang dipercayai yang sama, semakan asal masih lulus. Sumber, ID saluran, versi protokol, jenis mesej, dan pengesahan pelayan boleh mengehadkan sesi lama, salah hala (misrouting), dan impak perniagaan, tetapi ia tidak dapat menahan kod berniat jahat pada asal tersebut. Pelayar menganggap seluruh asal sebagai satu prinsipal keselamatan. Aplikasi pada tahap kepercayaan yang berbeza mesti menggunakan subdomain yang berbeza; laluan URL dan medan mesej tidak boleh mengasingkannya.
Dengan beberapa iframe pembayaran pada satu halaman, simpan rekod contentWindow, keadaan, saluran, dan pengendali yang berasingan bagi setiap elemen. Satu pendengar global boleh menghalakan mesej kepada contoh-contoh tertentu, tetapi ia mesti terlebih dahulu memetakan rujukan event.source kepada satu contoh. Ia tidak boleh bermula dengan mempercayai ID contoh yang dibekalkan di dalam mesej.
Langkah enam: sekat keupayaan iframe dan hubungan pembenaman
frame-src bagi CSP hos hanya membenarkan asal pembayaran yang diluluskan. frame-ancestors bagi tapak pembayaran hanya membenarkan hos yang diluluskan untuk membenamkannya. sandbox bagi iframe hanya mendayakan keupayaan yang sebenarnya diperlukan oleh aliran pembayaran, seperti skrip, borang, atau pop timbul tertentu. Setiap kebenaran yang ditambah harus sepadan dengan keperluan yang boleh diuji.
Kawalan ini menjawab siapa yang boleh memuatkan siapa dan keupayaan pelayar yang mana dimiliki oleh dokumen terbenam. Kawalan tersebut tidak mengesahkan mesej atau menjadikan "*" selamat. Jika mana-mana tapak boleh membenamkan widget pembayaran yang disahkan, penyerang boleh memuatkannya dalam halaman yang dikawal oleh penyerang dan menghantar arahan secara aktif. frame-ancestors menyempitkan laluan tersebut secara langsung.
Jika rakan sebaya memerlukan aliran bebas berfrekuensi tinggi selepas jabat tangan, postMessage pertama yang disahkan boleh memindahkan MessagePort. Komunikasi seterusnya kemudiannya menggunakan port khusus, mengurangkan gangguan dalam kalangan pendengar message global. Penghantaran port awal masih memerlukan semakan asal, sumber, dan skema, dan pemilikan port masih tidak memberikan sebarang kuasa perniagaan di sebelah pelayan.
Langkah tujuh: buktikan laluan penolakan dengan ujian negatif
Ujian positif hanya membuktikan bahawa halaman yang sah berfungsi. Pengesahan keselamatan membina input yang mesti ditolak:
| Ujian | Hasil yang dijangka |
|---|---|
Asal penyerang menghantar complete yang berbentuk baik | Semakan asal menolaknya; tiada pertanyaan pembayaran dijalankan |
| Iframe lain pada asal yang dipercayai menghantar mesej | Semakan sumber menolaknya |
| Asal dan sumber yang betul menghantar jenis yang tidak diketahui atau medan bersaiz lebih | Pengesahan skema menolaknya |
messageId yang sama dimainkan semula | Ia dikendalikan sekali sahaja |
| Saluran lama menghantar mesej lewat selepas penciptaan semula iframe | Semakan saluran menolaknya |
| Iframe bernavigasi ke asal lain sebelum induk menghantar | targetOrigin yang tepat menyebabkan mesej dibuang |
complete membawa hasil yang tiada atau dimiliki oleh pengguna lain | Kebenaran pelayan dan carian berwibawa menolaknya |
ready lewat, diduplikasi, atau tidak pernah tiba | Pengendalian idempoten atau tamat masa memasuki keadaan kegagalan yang boleh dicuba semula |
Semakan kod juga mencari setiap panggilan postMessage untuk "*", setiap pendengar message, perbandingan asal kabur, event.data yang tidak disemak, dan laluan yang menulis data mesej kepada innerHTML. Ujian integrasi pelayar merangkumi pembuangan pendengar, penciptaan semula iframe, pelbagai contoh, dan perubahan laluan.
Contoh jawapan berkualiti tinggi
“Saya akan membahagikan saluran kepada sempadan penghantaran dan sempadan penerimaan. Induk menghantar hanya kepada contentWindow iframe yang disimpannya dan menggunakan https://pay.example.net sebagai targetOrigin yang tepat. Untuk setiap mesej yang masuk, pendengar membandingkan event.origin penuh dan rujukan contentWindow yang sama sebelum pengesahan skema masa jalan. Asal sahaja tidak mencukupi kerana halaman boleh mengandungi beberapa iframe asal sama. Sumber sahaja tidak mencukupi kerana tetingkap tersebut mungkin telah bernavigasi.
Saya akan mentakrifkan set mesej berversi yang kecil: ready, init, resize, cancel, dan complete. Induk mendaftarkan pendengarnya sebelum memuatkan iframe. Anak memasang pendengarnya dan menghantar ready; hanya selepas pengesahan induk mencipta ID saluran dan menghantar pengawalan. Setiap mesej kemudian membawa ID saluran yang sama dan ID mesej yang unik. Mesin keadaan dan set nyahduplikasi menolak mesej sebelum jabat tangan, pendua, penyusunan semula, dan regresi keadaan selepas selesai. Tamat masa jabat tangan memusnahkan iframe lama, manakala percubaan semula menggunakan rujukan tetingkap dan saluran baharu.
Mesej penyiapan tidak pernah mengubah pesanan secara langsung. Ia hanya membawa rujukan hasil legap (opaque). Pelayan hos mengesahkan pengguna dan pesanan serta menanyakan sistem pembayaran untuk status yang berwibawa. Oleh itu, pepijat atau XSS pada asal pembayaran yang dipercayai tidak dapat memalsukan pembayaran dengan satu mesej.
Saya juga akan menyekat komponen tersebut dengan frame-src hos, frame-ancestors halaman pembayaran, dan kebenaran kotak pasir (sandbox) minimum. Ujian akan merangkumi aliran sah ditambah dengan asal penyerang, iframe asal sama yang salah, saluran lama, main semula, navigasi iframe, dan tamat masa kesediaan. Setiap laluan penolakan mesti mengelakkan tindakan perniagaan yang sensitif.”
Kesilapan biasa
- Menghantar dengan
"*"→ tetingkap sasaran mungkin telah bernavigasi ke halaman penyerang dan masih menerima data sensitif → sentiasa gunakantargetOriginyang tepat seperti yang dijangkakan. - Hanya memeriksa
event.data.typesemasa penerimaan → mana-mana halaman dengan rujukan tetingkap boleh memalsukan arahan yang dinamakan → sahkan asal yang tepat dan sumber yang dijangka sebelum menghuraikan data. - Menerima asal melalui substring atau serpihan akhiran domain → domain penyerang boleh mengandungi teks yang dipercayai → bandingkan asal dinormalkan penuh yang dibekalkan oleh pelayar.
- Memproses selepas penegasan TypeScript → jenis tidak wujud pada masa jalan, jadi data yang salah bentuk masih memasuki logik → mulakan dengan
unknowndan lakukan pengesahan skema, julat, dan keadaan yang ketat. - Menghantar
initserta-merta selepas halaman dimuatkan → pendengar iframe mungkin belum didaftarkan dan mesej akan hilang → biarkan anak mengumumkanready, sahkan ia, kemudian lakukan pengawalan dengan tamat masa. - Menganggap
completesebagai bukti pembayaran → mesej frontend bukan fakta perniagaan yang berwibawa, malah asal yang dipercayai juga boleh dikompromi → sahkan pada pelayan hos dan tanya keadaan pembayaran yang berwibawa. - Menghentikan semakan asal selepas jabat tangan → tetingkap boleh bernavigasi semasa sesi dan membawa kepercayaan lama merentasi dokumen → sahkan setiap mesej dan asingkan sesi yang dicipta semula dengan saluran baharu.
- Menganggap CORS atau sandbox sudah menjamin keselamatan mesej → mekanisme tersebut mengekang bacaan rangkaian dan keupayaan dokumen, bukan identiti atau data mesej → kekalkan semakan peringkat mesej dan gunakan dasar pelayar sebagai pertahanan mendalam (defense in depth).
Soalan susulan dan respons
Susulan satu: Widget mesti menyokong ribuan domain tersuai pelanggan. Bagaimanakah anak mengetahui asal induk?
Jangan mempercayai event.origin mesej pertama secara automatik. Hos terlebih dahulu mencipta sesi pembenaman dengan pelayan. Pelayan mengesahkan pemilikan domain pelanggan dan mengikat asal induk yang dibenarkan kepada sesi jangka pendek. Halaman pembayaran memperoleh asal yang dijangka daripada sesi tersebut dan hanya menggunakan nilai itu untuk penghantaran dan penerimaan. Tamat tempoh sesi, perubahan domain, atau penciptaan semula tetingkap memerlukan pengesahan semula. Domain tersuai yang tidak dapat dibuktikan tidak boleh menerima keupayaan pembenaman yang sensitif.
Susulan dua: Beberapa iframe asal sama memerlukan pemesejan. Bolehkah channelId sahaja menghalakannya?
Pengendali tidak boleh bermula dengan mempercayai saluran yang diisytiharkan oleh mesej. Pendengar global terlebih dahulu menggunakan event.source untuk mencari contoh dalam daftar rujukan Window yang diketahui, kemudian menyemak asal, keadaan, dan ID saluran contoh tersebut. Saluran menolak mesej sesi lama dan mesej yang tidak mengikut urutan; rujukan tetingkap mengenal pasti konteks penyemakan imbas. Kedua-duanya mempunyai tujuan yang berbeza.
Susulan tiga: Iframe melawat halaman log masuk dan kemudian halaman daftar keluar pada asal pembayaran yang sama. Bagaimanakah jabat tangan berfungsi?
Log masuk dan daftar keluar pada satu asal ialah prinsipal keselamatan pelayar yang sama; induk tidak dapat mengetahui laluan daripada event.origin. Jika kedua-duanya dipercayai sama rata, setiap load iframe menyebabkan induk membuang saluran lama dan kembali kepada pemuatan. Ia berjabat tangan semula hanya selepas dokumen baharu menghantar ready yang sepadan dengan kontrak sesi, yang menolak mesej lewat daripada dokumen sebelumnya. Jika log masuk tidak boleh melihat data pengawalan atau mempunyai tahap kepercayaan yang lebih rendah, alihkan ia ke asal yang lain dan berikan daftar keluar titik masuk pembenaman khusus. ID saluran tidak boleh membaiki pengasingan asal sama yang hilang.
Susulan empat: Adakah anda masih menyemak asal selepas beralih kepada MessageChannel?
Mesej port tidak membawa medan asal yang sama seperti mesej tetingkap, jadi keselamatan bergantung pada siapa yang mula-mula menerima port tersebut. postMessage pertama yang memindahkannya mesti mengesahkan asal yang tepat, sumber, dan keadaan jabat tangan. Port itu hanya milik sesi semasa dan dimusnahkan apabila ditutup. Port khusus mengurangkan salah hala, tetapi ia tidak menggantikan pengesahan awal, skema mesej, atau kebenaran pelayan.
Susulan lima: Iframe mengawal perubahan ketinggian automatik. Bagaimanakah anda menghalangnya daripada meregangkan halaman kepada saiz yang melampau?
Malah resize yang disahkan identitinya ialah input perniagaan yang tidak dipercayai. Protokol hanya menerima integer terhingga; induk mengehadkannya kepada ketinggian minimum dan maksimum yang ditakrifkan oleh produk serta mengehadkan kadar kemas kini (rate-limit). Ia merekodkan sebab penolakan untuk mesej di luar julat atau berlebihan. Jika kandungan benar-benar memerlukan lebih banyak ruang, gunakan penatalan dalaman (internal scrolling) atau tentukan had produk baharu daripada memberi anak kawalan CSS sewenang-wenangnya.