Topik wawancara representatif

Frontend Interview: Bagaimana Cara Mengamankan Komunikasi Cross-Origin iframe dengan postMessage?

FrontendSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Halaman host harus berkomunikasi dua arah dengan iframe pembayaran cross-origin melalui postMessage. Host mengirimkan data inisialisasi, sementara iframe melaporkan kesiapan, perubahan ukuran, dan penyelesaian pembayaran. Bagaimana Anda mencegah halaman berbahaya atau jendela yang salah memalsukan perintah atau menerima data, dan bagaimana Anda menangani pemuatan, replay, navigasi, serta pemulihan kegagalan?

Prompt dan skenario yang berlaku

Host berjalan di https://app.example.com dan menyematkan iframe pembayaran dari https://pay.example.net. Setelah widget siap, host mengirimkan lokal, tema, dan referensi sesi pembayaran berumur pendek (short-lived). Iframe melaporkan ready, perubahan tinggi, pembatalan pengguna, dan penyelesaian alur pembayaran. Halaman mungkin berisi beberapa iframe same-origin, dan widget mungkin dialihkan atau dibuat ulang saat dimuat.

Rancang protokol postMessage dua arah dan implementasi frontend-nya. Cakup jendela tujuan, identitas penerima, bentuk pesan, waktu inisialisasi, duplikasi dan pengurutan ulang, navigasi, pembersihan (cleanup), dan pengujian keamanan. Pesan penyelesaian hanya memicu UI untuk menyegarkan diri; server host harus mengonfirmasi status pembayaran akhir dengan sistem pembayaran otoritatif.

Pertanyaan ini cocok untuk peran frontend senior, Web platform, arsitektur frontend, dan keamanan aplikasi. Keterampilan intinya adalah browser same-origin policy, cross-document messaging, batasan kepercayaan klien (client trust boundaries), dan perancangan protokol asinkron, sehingga kategorinya adalah frontend. CORS mengontrol apakah skrip browser dapat membaca respons jaringan cross-origin. CORS tidak menggantikan batasan tujuan postMessage atau validasi pendengar pesan (message listener).

Apa yang dievaluasi oleh pewawancara

Sinyal pertama adalah apakah kandidat melindungi pengirim dan penerima. Pengirim memberikan targetOrigin yang tepat sehingga data tidak dikirimkan setelah jendela target bernavigasi ke origin lain. Penerima memeriksa event.origin pada setiap pesan dan, jika memiliki referensi jendela yang diharapkan, memeriksa event.source. Hanya mengimplementasikan salah satu sisi tetap meninggalkan jalur pengungkapan (disclosure) atau pemalsuan (forgery).

Sinyal kedua adalah apakah kandidat memperlakukan perpesanan sebagai titik masuk publik dengan input yang tidak diketahui. Lolos pemeriksaan origin hanya mengidentifikasi origin tempat kode dijalankan. Ini tidak membuktikan bentuk muatan (payload shape), juga tidak menghentikan XSS atau kode bermasalah pada origin tepercaya untuk mengirim perintah berbahaya. Jawaban yang kuat mendefinisikan amplop (envelope) berversi, tipe pesan yang diizinkan, batasan bidang (field constraints), batas ukuran, dan transisi status sebelum mempersempit event.data dari unknown.

Sinyal ketiga adalah penanganan waktu asinkron. Pesan inisialisasi yang dikirim sebelum iframe mendaftarkan pendengarnya akan hilang tanpa jejak. Alur yang andal mendaftarkan pendengar induk terlebih dahulu, memuat iframe, membiarkan anak mengumumkan ready, dan mengirim init hanya setelah validasi. ID pesan, ID saluran, batas waktu (timeout), dan transisi status yang idempoten menangani percobaan ulang, duplikat, dan pesan yang terlambat.

Terakhir, pewawancara mencari batas kepercayaan sisi server (server-side trust boundary). Pesan complete dari iframe yang terverifikasi tetap bukan bukti pembayaran. Frontend harus menggunakan referensi hasil tanpa detail sensitif untuk menanyakan server host. CSP, frame-src, frame-ancestors, dan izin minimal sandbox mengurangi paparan, tetapi tidak menggantikan identitas tingkat pesan dan validasi data.

Pertanyaan untuk diklarifikasi terlebih dahulu

  • Apakah kedua origin bersifat tetap? Dua origin tetap memungkinkan perbandingan persis. Jika host mendukung domain kustom pelanggan, halaman pembayaran harus mendapatkan origin induk yang diizinkan untuk sesi ini dari servernya. Halaman tersebut tidak boleh mempercayai event.origin mana pun yang muncul pertama kali.
  • Data sensitif apa yang melintasi saluran? Tema dan tinggi memiliki risiko rendah. Kredensial pembayaran, data pribadi, atau token pembawa (bearer tokens) yang dapat digunakan kembali tidak boleh dikirim melalui antarmuka bergaya siaran. Jika sebuah kapabilitas harus melintas, gunakan referensi berumur pendek, terikat audiens, dapat dicabut, dan berhak akses terendah (least-privilege).
  • Siapa yang boleh menyematkan halaman pembayaran? Halaman pembayaran harus membatasi penyemat dengan frame-ancestors. Jika ada banyak penyewa sah, buat kebijakan yang akurat di sisi server atau gunakan titik masuk penyematan yang terkontrol alih-alih mengizinkan setiap situs.
  • Berapa banyak iframe same-origin yang dapat berada di satu halaman? Dengan satu iframe, origin ditambah contentWindow yang diharapkan dapat menemukan peer. Beberapa instans memerlukan referensi jendela terpisah dan status protokol yang terikat saluran; penangan siaran berbasis origin saja tidak memadai.
  • Pesan mana yang memicu tindakan sensitif? resize dapat memengaruhi tata letak secara langsung. complete, pengembalian dana, pengiriman pesanan, atau perubahan akun memerlukan otorisasi server dan pencarian status otoritatif. Pesan hanya membawa sinyal, bukan otoritas bisnis.
  • Apa yang dapat dicoba ulang setelah kegagalan? ready dan init dapat dicoba ulang secara idempoten. Pesan yang dikirim ulang tidak boleh mengeksekusi pengiriman pembayaran dua kali. Tentukan siapa yang memiliki ID pesan, status terminal, dan kunci idempotensi server.

Kerangka jawaban 30 detik

“Saya akan memperlakukan postMessage sebagai API asinkron yang melintasi batas kepercayaan. Induk mendaftarkan pendengarnya dan menyimpan contentWindow iframe sebelum anak mengirim ready. Untuk setiap pesan, induk memverifikasi origin persis, sumber yang diharapkan, dan skema runtime, lalu membalas dengan init menggunakan targetOrigin yang persis. Protokol memiliki versi, ID saluran, dan ID pesan, sementara mesin status (state machine) menolak pesan sebelum handshake, duplikat, pengurutan ulang, dan perubahan setelah status terminal. complete hanya meminta host untuk memeriksa status pembayaran otoritatif melalui servernya. Saya akan menguji origin berbahaya, iframe same-origin yang salah, data yang salah bentuk, replay, dan race condition navigasi, lalu mengurangi paparan dengan CSP dan izin iframe minimal.”

Pembahasan mendalam langkah demi langkah

Langkah satu: petakan batas kepercayaan di kedua arah

Sebelum induk mengirim, ada dua pertanyaan: apakah referensi Window miliknya adalah milik iframe yang dituju, dan apakah dokumen target masih memiliki origin yang diharapkan saat panggilan dijalankan. targetOrigin menjawab pertanyaan kedua. Jika target bernavigasi ke tempat lain, browser akan membuang pesan tersebut. Menggunakan "*" menghapus batasan penerima tersebut.

Penerimaan juga memiliki dua pertanyaan independen: origin mana yang mengirim pesan, dan jendela mana di origin tersebut yang mengirimkannya. Halaman mana pun yang memperoleh referensi ke jendela saat ini dapat mencoba mengirim pesan. Iframe yang berbeda pada origin tepercaya yang sama juga dapat memancarkan event dengan nama yang sama. Oleh karena itu, penerima memeriksa setidaknya:

  1. event.origin sama persis dengan skema lengkap, host, dan port;
  2. event.source adalah referensi yang sama dengan contentWindow iframe yang disimpan;
  3. event.data cocok dengan bentuk pesan yang diizinkan oleh status protokol saat ini.

Jangan gunakan pemeriksaan akhiran (suffix containment), fragmen regex, atau indexOf untuk menerima origin. https://pay.example.net.attacker.test dapat lolos dari pemeriksaan substring yang longgar. Jangan pula menambahkan event.origin ke daftar izin (allowlist) secara dinamis; itu mengubah penyelidikan (probe) pertama penyerang menjadi registrasi.

Langkah dua: tentukan protokol pesan yang ringkas dan eksplisit

Representasikan pesan sebagai discriminated union, bukan objek arbitrer atau perintah string. Protokol yang ringkas dapat berisi:

KolomTujuanValidasi
vVersi protokolTerima hanya versi bilangan bulat yang didukung
typeTipe pesanEnum tetap; jangan pernah memanggil nama fungsi dinamis
messageIdDeduplikasi dan korelasi auditTidak kosong, panjang terbatas, unik dalam jendela saat ini
channelIdMengikat satu handshake yang berhasilDibuat oleh induk setelah ready; setiap pesan berikutnya harus cocok
Bidang bisnisData minimum yang dibutuhkan oleh pesan tersebutValidasi setiap tipe, rentang, dan panjang

ready tidak memiliki channelId sebelum saluran ada. Induk menerimanya melalui origin dan sumber yang telah diverifikasi, membuat channelId acak, dan mengirim init. Pesan resize, cancel, dan complete berikutnya harus mencantumkan ulang ID saluran tersebut. Saluran memisahkan sesi lama dan pesan yang terlambat di jendela yang sama. Saluran tidak menggantikan origin, sumber, atau otorisasi server.

Mulai penguraian (parsing) penerima dari unknown. Ini adalah contoh induk TypeScript yang disederhanakan. parseWidgetMessage mewakili validasi runtime yang ketat, bukan asersi tipe:

typescript
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)
  }
}

Pengurai sebenarnya juga menolak tipe berbahaya yang tidak dikenali, string yang terlalu besar, angka non-finit, dan kombinasi status yang tidak diizinkan. Jangan gunakan as WidgetMessage untuk melewati pemeriksaan runtime. Structured clone dapat membawa objek; ini tidak membuktikan bahwa suatu objek memenuhi protokol aplikasi.

Anak menerapkan aturan yang sama ke arah sebaliknya. Anak hanya menerima origin host yang dikonfigurasi sebelumnya atau terikat oleh sesi sisi server, memerlukan event.source === window.parent, menyimpan ID saluran hanya setelah memvalidasi skema init, dan selalu membalas dengan origin host yang tepat. Tidak ada peer yang boleh mengabaikan validasi hanya karena hanya mengharapkan satu rekanan.

Langkah tiga: hilangkan ambiguitas waktu dengan handshake dan mesin status

Standar HTML memperingatkan bahwa dokumen anak yang baru dinavigasi mungkin belum memasang pendengar pesannya. Pesan induk yang dikirim saat itu tidak menunggu dalam antrean hingga anak siap. Induk memasang pendengarnya sebelum menyetel atau mengonfirmasi URL iframe. Anak memasang pendengarnya dan mengumumkan ready. Induk mengirimkan inisialisasi sensitif hanya setelah ready lolos pemeriksaan origin, sumber, dan skema.

Mesin status memperjelas tindakan yang diizinkan:

Status saat iniPesan yang diterimaStatus setelahnya
loadingreadyactive
activeresize, cancel, completeSama, closed, atau completed
completedTidak ada pesan bisnis; konfirmasi hanya-baca opsionalTetap completed
closedTidak adaTetap closed

Induk dapat menerapkan batas waktu (timeout) pada handshake. Saat batas waktu habis, induk menampilkan kesalahan yang dapat dicoba ulang dan menghancurkan iframe lama. Membuat ulang iframe memerlukan ID saluran baru, kumpulan deduplikasi kosong, referensi jendela yang diharapkan yang diperbarui, dan penghapusan pendengar lama. Menggunakan kembali saluran lama akan memungkinkan pesan terlambat dari halaman sebelumnya masuk ke sesi baru.

Langkah empat: pisahkan pesan duplikat, tindakan bisnis duplikat, dan fakta server

Pengiriman pesan dan eksekusi bisnis memerlukan dua lapisan idempotensi. Frontend menggunakan messageId untuk mengabaikan pesan UI duplikat dan mesin status untuk menolak perubahan setelah status terminal. Server masih memerlukan kunci idempotensi pesanan atau upaya pembayaran untuk mencegah tagihan ganda, karena penyegaran halaman, percobaan ulang jaringan, dan banyak tab dapat melewati kumpulan frontend.

complete hanya berarti bahwa jendela tepercaya mengklaim alur telah selesai. Induk mengirimkan resultRef ke servernya sendiri. Server memverifikasi pengguna saat ini, kepemilikan pesanan, jumlah, dan status penyedia pembayaran otoritatif sebelum mengembalikan hasil yang dapat ditampilkan. Bahkan jika XSS mengontrol skrip pada origin iframe pembayaran, complete palsu tidak dapat secara langsung menandai pesanan telah dibayar.

Log pesan hanya berisi versi protokol, tipe, hash saluran, hasil, dan alasan penolakan. Log tidak berisi kredensial pembayaran, data pribadi lengkap, atau token yang dapat digunakan kembali. Batasi kumpulan deduplikasi atau hancurkan bersama saluran sehingga serangan atau halaman yang berjalan lama tidak dapat menghabiskan memori tanpa batas.

Langkah lima: tangani navigasi, banyak instans, dan origin bersama

event.origin adalah origin pengirim saat memanggil postMessage. Ini tidak menjamin bahwa jendela pengirim memiliki origin saat ini atau masa depan yang sama. Validasi ulang setiap pesan daripada mempercayai jendela selamanya setelah satu kali handshake. Jika iframe target bernavigasi ke origin penyerang, targetOrigin yang persis akan menghentikan pesan induk berikutnya, dan penerima induk menolak pesan baru karena origin-nya berbeda.

Jika iframe bernavigasi ke aplikasi yang berbeda pada origin tepercaya yang sama, pemeriksaan origin tetap lolos. Sumber, ID saluran, versi protokol, tipe pesan, dan konfirmasi server dapat membatasi sesi lama, salah perutean, dan dampak bisnis, tetapi tidak dapat menahan kode berbahaya pada origin tersebut. Browser memperlakukan seluruh origin sebagai satu entitas keamanan (security principal). Aplikasi pada tingkat kepercayaan yang berbeda harus menggunakan subdomain yang berbeda; jalur URL dan bidang pesan tidak dapat mengisolasinya.

Dengan beberapa iframe pembayaran pada satu halaman, simpan contentWindow, status, saluran, dan catatan penangan terpisah untuk setiap elemen. Satu pendengar global dapat merutekan ke instans-instans, tetapi pendengar tersebut harus terlebih dahulu memetakan referensi event.source ke sebuah instans. Pendengar tidak boleh memulai dengan mempercayai ID instans yang disediakan di dalam pesan.

Langkah enam: batasi kapabilitas iframe dan hubungan penyematan

frame-src pada CSP host hanya mengizinkan origin pembayaran yang disetujui. frame-ancestors pada situs pembayaran hanya mengizinkan host yang disetujui untuk menyematkannya. sandbox pada iframe hanya mengaktifkan kapabilitas yang benar-benar dibutuhkan oleh alur pembayaran, seperti skrip, formulir, atau popup tertentu. Setiap izin yang ditambahkan harus sesuai dengan kebutuhan yang dapat diuji.

Kontrol ini menentukan siapa yang dapat memuat siapa dan kapabilitas browser apa yang dimiliki dokumen yang disematkan. Kontrol ini tidak mengautentikasi pesan atau membuat "*" aman. Jika ada situs yang dapat menyematkan widget pembayaran yang diautentikasi, penyerang dapat memuatnya di halaman yang dikendalikan penyerang dan secara aktif mengirim perintah. frame-ancestors secara langsung mempersempit jalur tersebut.

Jika peer memerlukan aliran independen berfrekuensi tinggi setelah handshake, postMessage pertama yang diautentikasi dapat mentransfer MessagePort. Komunikasi berikutnya kemudian menggunakan port khusus, mengurangi interferensi di antara pendengar message global. Pengiriman port awal tetap memerlukan pemeriksaan origin, sumber, dan skema, dan kepemilikan port tetap tidak memberikan otoritas bisnis sisi server.

Langkah tujuh: buktikan jalur penolakan dengan pengujian negatif

Tes positif hanya membuktikan bahwa halaman yang sah berfungsi. Verifikasi keamanan menyusun input yang harus ditolak:

TesHasil yang diharapkan
Origin penyerang mengirimkan complete dengan bentuk yang benarPemeriksaan origin menolaknya; tidak ada kueri pembayaran yang dijalankan
Iframe lain pada origin tepercaya mengirimkan pesanPemeriksaan sumber menolaknya
Origin dan sumber yang benar mengirimkan tipe yang tidak dikenal atau bidang yang terlalu besarValidasi skema menolaknya
messageId yang sama diputar ulang (replayed)Pesan tersebut ditangani satu kali saja
Saluran lama mengirimkan pesan terlambat setelah iframe dibuat ulangPemeriksaan saluran menolaknya
Iframe bernavigasi ke origin lain sebelum induk mengirimtargetOrigin yang persis menyebabkan pesan dibuang
complete membawa hasil yang hilang atau milik pengguna lainOtorisasi server dan pencarian otoritatif menolaknya
ready terlambat, terduplikasi, atau tidak pernah tibaPenanganan idempoten atau batas waktu memasuki status kegagalan yang dapat dicoba ulang

Tinjauan kode juga memeriksa setiap panggilan postMessage untuk mencari "*", setiap pendengar message, perbandingan origin yang tidak tepat (fuzzy), event.data yang tidak dicentang, dan jalur yang menulis data pesan ke innerHTML. Pengujian integrasi browser mencakup pelepasan pendengar (teardown), pembuatan ulang iframe, beberapa instans, dan perubahan rute.

Contoh jawaban berkualitas tinggi

“Saya akan membagi saluran menjadi batas pengiriman dan batas penerimaan. Induk hanya mengirim ke contentWindow iframe yang disimpannya dan menggunakan https://pay.example.net sebagai targetOrigin yang persis. Untuk setiap pesan yang masuk, pendengar membandingkan event.origin lengkap dan referensi contentWindow yang sama sebelum validasi skema runtime. Origin saja tidak cukup karena halaman dapat berisi beberapa iframe same-origin. Sumber saja tidak cukup karena jendela tersebut mungkin telah bernavigasi.

Saya akan mendefinisikan sekumpulan kecil pesan berversi: ready, init, resize, cancel, dan complete. Induk mendaftarkan pendengarnya sebelum memuat iframe. Anak memasang pendengarnya dan mengirim ready; hanya setelah validasi, induk membuat ID saluran dan mengirim inisialisasi. Setiap pesan berikutnya membawa ID saluran yang sama dan ID pesan yang unik. Mesin status dan kumpulan deduplikasi menolak pesan sebelum handshake, duplikat, pengurutan ulang, dan regresi status setelah penyelesaian. Batas waktu handshake akan menghancurkan iframe lama, sementara percobaan ulang menggunakan referensi jendela dan saluran baru.

Pesan penyelesaian tidak pernah mengubah pesanan secara langsung. Pesan tersebut hanya membawa referensi hasil yang buram (opaque). Server host memvalidasi pengguna dan pesanan serta menanyakan sistem pembayaran untuk status otoritatif. Oleh karena itu, bug atau bahkan XSS pada origin pembayaran tepercaya tidak dapat memalsukan pembayaran dengan satu pesan saja.

Saya juga akan membatasi komponen dengan frame-src host, frame-ancestors halaman pembayaran, dan izin sandbox minimal. Pengujian akan mencakup alur yang sah ditambah origin penyerang, iframe same-origin yang salah, saluran lama, replay, navigasi iframe, dan batas waktu kesiapan. Setiap jalur penolakan harus menghindari tindakan bisnis yang sensitif.”

Kesalahan umum

  • Mengirim dengan "*" jendela target mungkin telah bernavigasi ke halaman penyerang dan tetap menerima data sensitif → selalu gunakan targetOrigin yang diharapkan secara persis.
  • Hanya memeriksa event.data.type saat menerima → halaman mana pun yang memiliki referensi jendela dapat memalsukan perintah tersebut → verifikasi origin persis dan sumber yang diharapkan sebelum mengurai data.
  • Menerima origin berdasarkan substring atau fragmen akhiran domain → domain penyerang dapat memuat teks tepercaya → bandingkan origin lengkap yang telah dinormalisasi yang disediakan oleh browser.
  • Memproses setelah asersi TypeScript → tipe data tidak ada saat runtime, sehingga data yang salah bentuk tetap masuk ke logika → mulai dengan unknown dan lakukan validasi skema, rentang, dan status yang ketat.
  • Mengirim init segera setelah pemuatan halaman → pendengar iframe mungkin belum terdaftar dan pesan menghilang → biarkan anak mengumumkan ready, validasi, lalu lakukan inisialisasi dengan batas waktu.
  • Memperlakukan complete sebagai bukti pembayaran → pesan frontend bukanlah fakta bisnis yang otoritatif, dan origin tepercaya pun dapat disusupi → otorisasi di server host dan tanyakan status pembayaran otoritatif.
  • Menghentikan pemeriksaan origin setelah handshake → jendela dapat bernavigasi selama sesi dan membawa kepercayaan lama melintasi dokumen → validasi setiap pesan dan isolasi sesi yang dibuat ulang dengan saluran baru.
  • Menganggap CORS atau sandbox sudah mengamankan pesan → mekanisme tersebut membatasi pembacaan jaringan dan kapabilitas dokumen, bukan identitas pesan atau data → pertahankan pemeriksaan tingkat pesan dan gunakan kebijakan browser sebagai pertahanan berlapis (defense in depth).

Pertanyaan lanjutan dan tanggapan

Lanjutan satu: Widget harus mendukung ribuan domain kustom pelanggan. Bagaimana anak mengetahui origin induk?

Jangan secara otomatis mempercayai event.origin dari pesan pertama. Host terlebih dahulu membuat sesi penyematan dengan server. Server memverifikasi kepemilikan domain pelanggan dan mengikat origin induk yang diizinkan ke sesi berumur pendek. Halaman pembayaran memperoleh origin yang diharapkan dari sesi tersebut dan hanya menggunakan nilai itu untuk mengirim dan menerima. Kedaluwarsa sesi, perubahan domain, atau pembuatan ulang jendela memerlukan otorisasi ulang. Domain kustom yang tidak dapat dibuktikan tidak boleh menerima kapabilitas penyematan sensitif.

Lanjutan dua: Beberapa iframe same-origin memerlukan perpesanan. Bisakah channelId saja merutekannya?

Penangan tidak dapat memulai dengan mempercayai saluran yang dideklarasikan oleh pesan. Pendengar global terlebih dahulu menggunakan event.source untuk menemukan instans dalam registri referensi Window yang diketahui, lalu memeriksa origin, status, dan ID saluran instans tersebut. Saluran menolak sesi lama dan pesan yang tidak berurutan; referensi jendela mengidentifikasi konteks penjelajahan. Keduanya memiliki tujuan yang berbeda.

Lanjutan tiga: Iframe mengunjungi halaman login lalu halaman checkout pada origin pembayaran yang sama. Bagaimana cara kerja handshake?

Login dan checkout pada satu origin adalah entitas keamanan browser yang sama; induk tidak dapat mengetahui jalurnya dari event.origin. Jika keduanya memiliki tingkat kepercayaan yang sama, setiap load iframe membuat induk membuang saluran lama dan kembali ke status memuat. Induk melakukan handshake lagi hanya setelah dokumen baru mengirim ready yang cocok dengan kontrak sesi, yang menolak pesan terlambat dari dokumen sebelumnya. Jika login tidak boleh melihat data inisialisasi atau memiliki tingkat kepercayaan lebih rendah, pindahkan ke origin lain dan beri checkout titik masuk penyematan khusus. ID saluran tidak dapat memperbaiki isolasi same-origin yang hilang.

Lanjutan empat: Apakah Anda masih memeriksa origin setelah beralih ke MessageChannel?

Pesan port tidak membawa bidang origin yang sama seperti pesan jendela, sehingga keamanan bergantung pada siapa yang awalnya menerima port tersebut. postMessage pertama yang mentransfernya harus memverifikasi origin, sumber, dan status handshake yang tepat. Port hanya milik sesi saat ini dan dihancurkan saat ditutup. Port khusus mengurangi salah perutean, tetapi tidak menggantikan autentikasi awal, skema pesan, atau otorisasi server.

Lanjutan lima: Iframe mengontrol perubahan tinggi otomatis. Bagaimana Anda mencegahnya meregangkan halaman ke ukuran ekstrem?

Bahkan resize yang identitasnya terverifikasi adalah input bisnis yang tidak tepercaya. Protokol hanya menerima bilangan bulat finit; induk membatasi nilainya pada batas minimum dan maksimum yang ditentukan produk serta membatasi laju pembaruan (rate-limit). Induk mencatat alasan penolakan untuk pesan yang di luar rentang atau berlebihan. Jika konten benar-benar membutuhkan lebih banyak ruang, gunakan pengguliran internal atau tentukan batas produk baru alih-alih memberi anak kontrol CSS arbitrer.

Sumber publik

Pertanyaan terkait