IlmHamroh
JavaScript Full-stack/4-qism. HTML32/86-dars10 daqiqa
Mundarija (28)

iframe xavfsizligi va unumdorligi: sandbox, clickjacking va facade

Qisqacha: Iframe ichida begona kod ishlaydi — sandbox atributi uni "qafasga" soladi: skriptlar, formalar, yangi oynalar standart holatda taqiqlanadi va kerakligigina allow-... bilan qaytariladi. Teskari xavf ham bor: hujumchi sizning sahifangizni o'z saytida ko'rinmas iframe'ga qo'yib, foydalanuvchini aldab bostiradi (clickjacking). Undan server sarlavhalari himoya qiladi. Og'ir iframe'lar uchun esa "facade" — oldin rasm, bosilgach haqiqiy iframe.

Bu darsda

  • sandbox bilan begona kontentni cheklaysiz va kerakli ruxsatlarni qaytarasiz.
  • srcdoc bilan iframe ichiga to'g'ridan-to'g'ri HTML yozasiz.
  • Clickjacking hujumi qanday ishlashini tushuntira olasiz.
  • X-Frame-Options va frame-ancestors sarlavhalarining vazifasini bilasiz.
  • Og'ir YouTube iframe'ini facade usuli bilan almashtirasiz.

Oldin bilishingiz kerak: iframe: boshqa sahifani joylash, Origin va Same-Origin Policy.

1. Nega bu kerak?

O'tgan darsda iframe'ni "qo'shni hovliga qaraydigan deraza" deb atadik. Endi derazaning ikki xavfli tomonini ko'ramiz.

Birinchi xavf — derazadan kirayotgan narsa. Siz joylagan begona sahifa sizning saytingiz ichida ko'rinadi. U reklama oynalarini ochishi, foydalanuvchini boshqa saytga yo'naltirishi yoki fayl yuklatishi mumkin. Foydalanuvchi esa "bu choyxona saytining ishi" deb o'ylaydi.

Ikkinchi xavf — sizning uyingiz boshqa birovning derazasida. Hujumchi sizning sahifangizni o'z saytiga joylaydi va foydalanuvchini aldaydi.

Uchinchi masala — tezlik. Bitta YouTube iframe'i sahifaga yuzlab kilobayt, ba'zan megabaytdan ortiq kod qo'shadi.

Bu dars — uchalasining ham yechimi.

2. sandbox — begona kontent uchun qafas

2.1 Bo'sh sandbox — eng qattiq

html
<iframe src="https://example.com/vidjet" sandbox
        title="Hamkor vidjeti" width="400" height="300">
</iframe>

sandbox ("qum qutisi" — bolalar xavfsiz o'ynaydigan joy) qiymatsiz yozilsa, iframe ichidagi sahifa uchun deyarli hamma narsa taqiqlanadi:

  • JavaScript ishlamaydi.
  • Formalarni yuborib bo'lmaydi.
  • Yangi oyna yoki qalqib chiquvchi oynalar ochilmaydi.
  • Asosiy sahifani boshqa manzilga yo'naltirib bo'lmaydi.
  • Sahifa "noma'lum origin" hisoblanadi — hatto sizning saytingizdan bo'lsa ham, uning cookie va ma'lumotlariga kira olmaydi.

Ya'ni iframe faqat HTML va CSS'ni ko'rsatadi, xolos.

2.2 Kerakli ruxsatlarni qaytarish

Ko'p vidjetlar JavaScript'siz ishlamaydi. sandbox ga qiymat sifatida faqat kerakli ruxsatlarni yozasiz:

Qiymat Nimaga ruxsat
allow-scripts JavaScript
allow-forms Formalarni yuborish
allow-popups Yangi oyna ochish
allow-same-origin O'z origin'ini saqlash (o'z cookie'lariga kirish)
allow-top-navigation-by-user-activation Foydalanuvchi bosganda asosiy sahifani yo'naltirish
allow-downloads Fayl yuklab olish
allow-modals alert kabi dialog oynalar
html
<iframe src="https://example.com/sorovnoma"
        sandbox="allow-scripts allow-forms"
        title="Mijozlar so'rovnomasi" width="400" height="500">
</iframe>

So'rovnoma skript va forma bilan ishlaydi, lekin yangi oyna ocha olmaydi va sahifangizni boshqa joyga yo'naltira olmaydi.

Tamoyil o'tgan darsdagi allow bilan bir xil: hammasini taqiqla, keraklisini ruxsat ber.

2.3 Xavfli juftlik

allow-scripts va allow-same-origin ni birga yozish, iframe'dagi sahifa sizning saytingizdan bo'lsa, qafasni ma'nosiz qiladi. Iframe'dagi skript o'z origin'i bilan asosiy sahifaga kira oladi va sandbox atributini o'zi olib tashlaydi. Validator ogohlantiradi:

text
Warning: Potentially bad value “allow-scripts allow-same-origin” for attribute “sandbox” on element “iframe”: Setting both “allow-scripts” and “allow-same-origin” is not recommended, because it effectively enables an embedded page to break out of all sandboxing.

Tarjimasi: "sandbox uchun ehtimoliy yomon qiymat: allow-scripts va allow-same-origin ni birga o'rnatish tavsiya etilmaydi, chunki bu joylangan sahifaga butun cheklovdan chiqib ketish imkonini beradi."

Tekshirib ko'ring: Iframe'da hamkorning xaritasi. U JavaScript bilan ishlaydi, boshqa hech narsa kerak emas. sandbox qiymati qanday bo'ladi?

Javob

sandbox="allow-scripts". Skriptlar ishlaydi, lekin formalar, yangi oynalar va asosiy sahifani yo'naltirish taqiqlangan. Agar xarita ishlamasa, DevTools Console'dagi xabarlardan qaysi ruxsat yetishmayotganini bilib, faqat o'shani qo'shasiz.

3. srcdoc — iframe ichiga HTML yozish

Ba'zan iframe'ga manzil emas, to'g'ridan-to'g'ri HTML matn kerak bo'ladi. Masalan, choyxona boshqaruv panelida administrator email xabarnoma shablonini yozadi va uni saqlashdan oldin "oldindan ko'rish" kerak.

html
<iframe sandbox title="Xat shablonini oldindan ko'rish"
        width="600" height="300"
        srcdoc="<h1>Buyurtmangiz tayyor!</h1>
                <p>Choyxona &quot;Bahor&quot; kutmoqda.</p>">
</iframe>

srcdoc — iframe ichidagi sahifaning HTML kodi. Bu kod atribut ichida bo'lgani uchun uning qo'shtirnoqlari escape qilinadi: &quot; (Maxsus belgilar darsidagi qoida).

Nega sandbox bilan? Chunki shablon matnini foydalanuvchi yozgan. Unda <script> bo'lsa, u sizning saytingiz nomidan ishga tushishi mumkin edi. sandbox uni zararsiz qiladi: shablon ko'rinadi, skriptlar esa ishlamaydi.

4. Hujumchi nigohi: clickjacking

4.1 Hujum qanday ishlaydi

Tasavvur qiling: choyxona saytida "Hisobni o'chirish" tugmasi bor. Mijoz tizimga kirgan (brauzerida uning cookie'si saqlangan).

  1. Hujumchi o'z saytini yaratadi: "Bepul osh yutib oling! Mana bu tugmani bosing".
  2. Shu sahifaga choyxonaning "Hisob sozlamalari" sahifasini ko'rinmas (shaffof) iframe qilib qo'yadi. Iframe'dagi "Hisobni o'chirish" tugmasi aynan "Bepul osh" tugmasining ustiga to'g'ri keladi.
  3. Mijoz "Bepul osh" ni bosadi. Aslida esa u ko'rinmas iframe'dagi haqiqiy tugmani bosdi — o'z hisobida, o'z cookie'si bilan.

Bu — clickjacking ("bosishni o'g'irlash"). Foydalanuvchi o'zi bosdi, lekin nimani bosayotganini ko'rmadi. Xuddi shu usul bilan "Obuna bo'lish", "To'lash", "Ruxsat berish" tugmalari o'g'irlanadi.

4.2 Himoya: "meni joylamang" deyish

Himoya HTML'da emas, server javobi sarlavhalarida yoziladi (HTTP sarlavhalari darsida ko'rgansiz). Server brauzerga aytadi: "bu sahifani boshqa saytlarning iframe'iga qo'yma".

Zamonaviy usul — Content Security Policy sarlavhasining frame-ancestors qismi:

text
Content-Security-Policy: frame-ancestors 'self'

'self' — "faqat o'z saytim meni joylashi mumkin". 'none' — "hech kim".

Eski, lekin hali keng qo'llanadigan usul — X-Frame-Options:

text
X-Frame-Options: SAMEORIGIN

SAMEORIGIN — faqat o'z saytingiz, DENY — hech kim. Ko'p saytlar ikkalasini birga yuboradi — eski brauzerlar uchun.

O'tgan darsda ko'rgan "refused to connect" xabari — aynan shu himoyaning natijasi: Google o'z sahifalarini shu sarlavhalar bilan himoya qiladi.

4.3 Nega meta bilan bo'lmaydi

head ichida meta teglari bilan ba'zi sarlavhalarni "taqlid" qilish mumkin. Lekin bu ikkitasi uchun — yo'q:

html
<meta http-equiv="X-Frame-Options" content="DENY">
text
Error: Bad value “X-Frame-Options” for attribute “http-equiv” on element “meta”.

Tarjimasi: "meta ning http-equiv atributi uchun 'X-Frame-Options' — yaroqsiz qiymat." Brauzer uni e'tiborsiz qoldiradi. frame-ancestors ham meta orqali ishlamaydi. Himoya faqat haqiqiy server sarlavhasi bilan.

Sarlavhani qanday qo'yish xostingga bog'liq. Masalan, Netlify'da loyiha papkasidagi _headers fayli orqali. GitHub Pages esa o'z sarlavhalaringizni qo'yishga ruxsat bermaydi. Serverni o'zingiz boshqarsangiz — server sozlamalarida. Buni HTML darajasidagi xavfsizlik darsida va backend qismida amalda ko'rasiz.

Qaysi sahifalarga kerak? Eng avvalo — foydalanuvchi harakat qiladigan hamma sahifaga: kirish, sozlamalar, to'lov, o'chirish. Yaxshi odat — butun sayt uchun frame-ancestors 'self'.

5. Facade — og'ir iframe'ni tezlashtirish

5.1 G'oya

YouTube iframe'i sahifa ochilishi bilan pleyerning butun kodini yuklaydi — foydalanuvchi videoni ijro etmasa ham. loading="lazy" yordam beradi, lekin foydalanuvchi pastga tushishi bilan baribir hammasi yuklanadi.

Facade ("fasad", "tashqi ko'rinish") usuli boshqacha: avval iframe o'rnida faqat videoning rasmi va ijro belgisi turadi. Foydalanuvchi uni bosgandagina haqiqiy iframe yuklanadi. Videoni ko'rmaydigan foydalanuvchi uchun pleyer kodi umuman yuklanmaydi.

5.2 Eng oddiy facade — JavaScript'siz

YouTube har bir videoning muqova rasmini ochiq manzilda beradi. Rasm va havola bilan eng oddiy facade:

html
<a href="https://www.youtube.com/watch?v=VIDEO_ID">
  <img src="https://i.ytimg.com/vi/VIDEO_ID/hqdefault.jpg"
       alt="Video: Rustam aka Toshkent oshini damlaydi"
       width="480" height="360" loading="lazy">
</a>

Bosilganda video YouTube'ning o'zida ochiladi. Sahifaga bitta rasm yuklanadi — pleyerning og'ir kodi emas.

5.3 JavaScript bilan facade

Video sahifaning o'zida ijro etilishi kerak bo'lsa, tayyor yechimlar bor. Eng mashhuri — lite-youtube-embed kutubxonasi: u iframe o'rnida rasm ko'rsatadi va bosilganda haqiqiy iframe'ni qo'yadi. Ularni JavaScript'ni o'rgangach ulaysiz. Muhimi — g'oyani bilish: "og'ir narsani foydalanuvchi so'raguncha yuklama".

Xuddi shu usul xaritalar va chat vidjetlari uchun ham ishlaydi: avval rasm yoki tugma, bosilganda haqiqiy vidjet.

6. Iframe bilan xabar almashish

Iframe va asosiy sahifa turli origin'da bo'lsa, ular bir-biriga to'g'ridan-to'g'ri kira olmaydi (Same-Origin Policy). Lekin xabar yuborishning xavfsiz kanali bor — JavaScript'dagi postMessage. Masalan, to'lov iframe'i "to'lov muvaffaqiyatli" deb asosiy sahifaga xabar beradi.

Bu JavaScript mavzusi. Hozir bitta xavfsizlik qoidasini eslab qoling: xabar qabul qilganda kim yuborganini (origin'ini) doim tekshirish kerak — aks holda istalgan sayt sizga soxta xabar yubora oladi.

7. Ko'p uchraydigan xatolar

7.1 Begona kontent sandbox siz

Foydalanuvchi yoki noma'lum hamkor HTML'i iframe'da hech qanday cheklovsiz. Tuzatish: sandbox va faqat kerakli allow-... qiymatlar.

7.2 Noto'g'ri sandbox qiymati

html
<iframe sandbox="allow-foo" src="a.html" title="B"></iframe>
text
Error: Bad value “allow-foo” for attribute “sandbox” on element “iframe”: The string “allow-foo” is not a valid keyword.

Tarjimasi: "sandbox uchun 'allow-foo' — yaroqsiz qiymat: bunday kalit so'z yo'q." Brauzer noma'lum qiymatni e'tiborsiz qoldiradi — siz ruxsat berdim deb o'ylaysiz, aslida esa yo'q. Tuzatish: qiymatlarni MDN'dagi ro'yxatdan tekshiring.

7.3 Muhim sahifalar himoyasiz

Kirish va to'lov sahifalarida frame-ancestors ham, X-Frame-Options ham yo'q — sahifani istalgan sayt joylashi mumkin. Tuzatish: server sarlavhasi. Tekshirish uchun: DevTools → Network → sahifa so'rovi → Headers bo'limida javob sarlavhalarini ko'ring.

7.4 Bitta sahifada o'nta video iframe

Kurs sahifasida 10 ta dars videosi — hammasi to'liq iframe. Sahifa bir necha megabayt og'irlashadi. Tuzatish: facade.

8. Mashqlar

1-mashq (oson): Qaysi qiymat?

  1. Iframe'da JavaScript'ga ruxsat berish uchun sandbox qiymati —
  2. Sahifani faqat o'z saytingiz joylashi uchun frame-ancestors qiymati (tirnoqsiz yozing) —
Yechim
  1. allow-scripts.
  2. self — sarlavhada u bittalik tirnoq bilan yoziladi: frame-ancestors 'self'.

2-mashq (o'rta): Xavfni toping

html
<iframe src="/admin/preview.html"
        sandbox="allow-scripts allow-same-origin allow-popups"
        title="Oldindan ko'rish"></iframe>
<meta http-equiv="X-Frame-Options" content="DENY">

preview.html — sizning saytingizdagi sahifa, u foydalanuvchi yozgan HTML'ni ko'rsatadi.

Yechim
  1. allow-scripts va allow-same-origin birga — va sahifa sizning saytingizdan. Foydalanuvchi HTML'idagi skript sandbox ni olib tashlab, sahifangizga kira oladi. Kerak bo'lmasa, allow-same-origin ni olib tashlang (yoki skriptlarni umuman taqiqlang).
  2. allow-popups — oldindan ko'rish uchun kerak emas.
  3. meta orqali X-Frame-Options ishlamaydi — himoya faqat server sarlavhasida.

Xavfsizroq variant:

html
<iframe src="/admin/preview.html" sandbox
        title="Oldindan ko'rish"></iframe>

3-mashq (qiyin): Tez va xavfsiz video bo'limi

  1. "Tadbirlar" sahifasida uchta YouTube videosini (istalgan, masalan osh retseptlari) JavaScript'siz facade shaklida qo'ying: muqova rasmi + havola.
  2. Har bir rasmning alt i videoning mazmunini aytsin, loading="lazy" va o'lchamlar bilan.
  3. Netlify'ga joylashtirilsa, butun sayt uchun frame-ancestors 'self' qo'yadigan _headers fayl matnini yozing (hozircha faqat faylni yarating — deploy'ni keyinroq qilamiz).
Yechim

Bitta video:

html
<a href="https://www.youtube.com/watch?v=VIDEO_ID">
  <img src="https://i.ytimg.com/vi/VIDEO_ID/hqdefault.jpg"
       alt="Video: qovoqli manti tayyorlash"
       width="480" height="360" loading="lazy">
</a>

_headers fayli (loyiha ildizida):

text
/*
  Content-Security-Policy: frame-ancestors 'self'
  X-Frame-Options: SAMEORIGIN

/* — "saytning hamma sahifalari uchun". Keyingi qatorlar — shu sahifalarga qo'shiladigan sarlavhalar (boshida ikki bo'sh joy bilan). Uni Birinchi deploy darsida ishlatamiz.

9. Real ishda

  • Bank va to'lov tizimlari clickjacking'ga qarshi sarlavhalarni hamma sahifada ishlatadi. Xavfsizlik auditida ular birinchi tekshiriladigan narsalardan.
  • Kontent tizimlari va email servislari foydalanuvchi HTML'ini sandbox + srcdoc bilan oldindan ko'rsatadi.
  • Onlayn kod muharrirlari (CodePen kabi) foydalanuvchi kodini sandbox li iframe'da, alohida domenda ishga tushiradi — aynan shu darsdagi xavflar tufayli.
  • Unumdorlik. Lighthouse "Lazy load third-party resources with facades" ("Uchinchi tomon resurslarini facade bilan kechiktirib yuklang") tavsiyasini beradi — u aynan YouTube va chat vidjetlarini ko'rsatadi.

Xulosa

  • Bo'sh sandbox — deyarli hamma narsani taqiqlaydi; kerakligini allow-scripts, allow-forms kabi qiymatlar bilan qaytaring.
  • O'z saytingizdagi sahifa uchun allow-scripts + allow-same-origin birga — qafasni buzadi.
  • srcdoc — iframe ichiga to'g'ridan-to'g'ri HTML; foydalanuvchi HTML'i uchun sandbox bilan.
  • Clickjacking — sahifangiz ko'rinmas iframe'ga qo'yilib, foydalanuvchi aldanadi.
  • Himoya — server sarlavhalari: frame-ancestors 'self' va X-Frame-Options; meta orqali ishlamaydi.
  • Facade — avval rasm, bosilgach og'ir iframe; eng oddiysi — muqova rasmli havola.

Keyingi dars: Semantik HTML nima va nega kerak — yangi modul: tegni ko'rinish uchun emas, ma'no uchun tanlashning butun sahifa darajasidagi ahamiyati.

Manbalar

  • MDN: <iframe> — sandbox va srcdoc; "Clickjacking"; "CSP: frame-ancestors"; "X-Frame-Options" — developer.mozilla.org
  • OWASP: "Clickjacking Defense Cheat Sheet" — cheatsheetseries.owasp.org
  • lite-youtube-embed — github.com/paulirish/lite-youtube-embed
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
iframe xavfsizligi va unumdorligi: sandbox, clickjacking va facade — IlmHamroh