IlmHamroh
JavaScript Full-stack/13-qism. Brauzer API'lari, performans va xavfsizlik32/32-dars23 daqiqa
Mundarija (38)

Brauzer xavfsizlik modeli: same-origin, CSP, COOP/COEP, sandbox va Permissions-Policy

Qisqacha: Brauzer bir vaqtda minglab saytlarning kodini ishlatadi va ularni devorlar bilan ajratadi. Asosiy devor — same-origin policy: bir origin boshqasining sahifasi, javobi va xotirasini o'qiy olmaydi. Qolgan devorlarni sayt o'zi sarlavhalar bilan qo'yadi: CSP (qaysi manbadan nima yuklanadi), COOP/COEP (oynani boshqalardan to'liq ajratish), sandbox va Permissions-Policy (iframe va sahifaga qaysi imkoniyatlar ruxsat). IlmHamroh'ning natija oynasi — bularning hammasi birga ishlayotgan jonli misol.

Bu darsda

  • Same-origin policy nimani taqiqlashini va nimaga ruxsat berishini kod bilan ko'rsata olasiz.
  • CORS, CSRF va SameSite bir-biriga qanday bog'liqligini tushuntira olasiz.
  • CSP direktivalarini o'qiy va yoza olasiz; meta va HTTP sarlavha farqini bilasiz.
  • SRI, secure context, COOP/COEP, sandbox va Permissions-Policy nima uchun kerakligini bilasiz.
  • vazifalar ga CSP va Trusted Types qo'yib, 13-qismdagi v4 ni yakunlaysiz.

Oldin bilishingiz kerak: XSS va DOM xavfsizligi, Origin va Same-Origin Policy, CORS mijoz tomondan, Cookie'lar JS'dan, iframe xavfsizligi va unumdorligi.

1. Nega bu kerak?

Jasur akaning telefonida bir vaqtda uchta tab ochiq: «Bahor» admin paneli, bank ilovasi va Telegram Web. Uchalasi ham JavaScript ishlatadi. Bank sahifasidagi skript «Bahor» dagi buyurtmalarni o'qiy oladimi? Begona reklama skripti bankdagi balansni-chi?

Yo'q — va buning sababi brauzerning xavfsizlik modeli. Ko'p qavatli uyni tasavvur qiling. Har bir kvartiraning o'z eshigi va kaliti bor (origin). Qo'riqchi (brauzer) begonani boshqa kvartiraga kiritmaydi. Lekin har bir xonadon egasi (sayt) o'z qoidalarini ham qo'yadi: "eshikni faqat shu odamlarga och", "derazadan hech narsa uloqtirilmasin".

Oldingi darsda XSS'dan kodning o'zida himoyalandik. Bu darsda brauzer beradigan devorlarni bittada yig'amiz. Ularning deyarli hammasini siz allaqachon ko'rgansiz — IlmHamroh'ning ```natija oynasida. Bugun shu oynani "ochib" ko'ramiz.

2. Same-origin policy: asosiy devor

2.1 Eslab olamiz

Origin va Same-Origin Policy darsida: origin — protokol + domen + port. https://ilmhamroh.uz va https://example.com — turli origin'lar. Same-origin policy (bir xil manba siyosati) qoidasi: bir origin'dagi skript boshqa origin'ning narsalarini o'qiy olmaydi.

Taqiqlangan (o'qish) Ruxsat etilgan (joylash, yuborish)
Boshqa origin iframe'ining DOM'i <img>, <script>, <iframe> bilan joylash
fetch javobi (CORS ruxsatisiz) Forma yuborish, havolaga o'tish
Uning localStorage, cookie, IndexedDB postMessage bilan xabar (Oyna va tablar)

Nimaga qarang: chapda — o'qish, o'ngda — yuborish va joylash. Brauzer begona narsani ko'rsatishga ruxsat beradi, lekin uning ichini ko'rishga — yo'q. Ikkinchi ustundagi "yuborish" ning o'z xavfi bor — uni CSRF bo'limida ko'ramiz.

2.2 Natija oynasi — jonli misol

Darslardagi ```natija oynasi — IlmHamroh sahifasi ichidagi iframe. Uning kodi qayerda ishlayotganini o'zidan so'raymiz:

html
<script>
  console.log("origin:", origin);
  console.log("ota sahifa:", location.ancestorOrigins[0]);
  try {
    console.log(parent.document.title);
  } catch (error) {
    console.log(`${error.name}: ${error.message}`);
  }
  console.log("xavfsiz kontekst:", isSecureContext);
  console.log("cross-origin isolated:", crossOriginIsolated);
</script>

Konsolda:

text
origin: null
ota sahifa: https://ilmhamroh.uz
SecurityError: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "null" from accessing a cross-origin frame.
xavfsiz kontekst: true
cross-origin isolated: false

Bu besh qatorni birma-bir ochamiz:

  • origin: null — oyna sandbox atributi bilan, lekin allow-same-origin siz yaratilgan. Brauzer unga "hech kimniki bo'lmagan" maxsus origin beradi. U hatto o'zi joylashgan sayt bilan ham bir origin emas.
  • ota sahifa — location.ancestorOrigins faqat ota sahifaning manzilini aytadi, ichiga kiritmaydi.
  • SecurityError — ota sahifaning document ini o'qishga urindik. Tarjimasi: "Window dan document xususiyatini o'qib bo'lmadi: null origin'li oyna boshqa origin'dagi oynaga kirishga urindi va to'sildi." Mana same-origin policy ishda: siz natija oynasida yozgan kod IlmHamroh'dagi akkauntingizga, tokeningizga, sahifaga tega olmaydi.
  • xavfsiz kontekst: true va cross-origin isolated: false — ularni pastda, alohida bo'limlarda ochamiz.

Shuning uchun 11-qismda natija oynasida localStorage o'rniga "o'rinbosar" ishladi: null origin'ning haqiqiy xotirasi yo'q.

2.3 CORS: devordagi eshik

CORS mijoz tomondan darsida ko'rgandik: CORS — same-origin policy'ni server ruxsati bilan yumshatish. Server javobga Access-Control-Allow-Origin sarlavhasini qo'ysa, brauzer begona origin'ga javobni o'qishga ruxsat beradi. Mashq API'si * qo'yadi — shuning uchun null origin'li natija oynasi ham undan menyu oladi. CORS — devorni ochish, xuddi pastdagi CSP esa sizning sahifangiz uchun yangi devor.

2.4 CSRF va SameSite: "yuborish" ning xavfi

Ruxsat etilgan ustunni eslang: begona sayt sizning saytingizga forma yubora oladi. Agar brauzer so'rovga sizning cookie'ingizni o'zi qo'shsa — server uni siz bosgan deb o'ylaydi. Bu CSRF (Cross-Site Request Forgery — saytlararo soxta so'rov). Cookie'lar JS'dan darsida Dilshod akaning bron bekor qilinishi misolini ko'rgandik.

Asosiy himoya — cookie'ning SameSite atributi:

Qiymat Begona saytdan kelgan so'rovda cookie
Strict Hech qachon yuborilmaydi
Lax Faqat oddiy havolaga o'tishda (GET); POST'da — yo'q
None Har doim (faqat Secure bilan)

Chrome'da atributsiz cookie Lax deb hisoblanadi. Server tomonidagi qo'shimcha himoya (CSRF tokeni, Origin sarlavhasini tekshirish) — Tokenni qayerda saqlash va CSRF darsida, backend qismida.

Tekshirib ko'ring: https://example.com sahifasidagi skript fetch("https://ilmhamroh.uz/api/...") yubordi. So'rov serverga yetib boradimi? Skript javobni o'qiy oladimi?

Javob

So'rov — ko'p hollarda yetib boradi: same-origin policy yuborishni emas, o'qishni to'xtatadi (murakkab so'rovlarda brauzer avval preflight so'raydi). Javobni o'qish esa faqat server CORS ruxsatini bergan bo'lsa mumkin. Shuning uchun server o'z holatini o'zgartiradigan so'rovlarni (POST, DELETE) CSRF'dan alohida himoya qilishi kerak — CORS bu vazifani bajarmaydi.

3. CSP: sahifa o'zi qo'yadigan devor

3.1 Direktivalar oilasi

XSS va DOM xavfsizligi darsida CSP'ning script-src va nonce qismini ko'rdik. To'liq CSP — direktivalar ro'yxati. Har biri "qaysi turdagi narsa qayerdan kelishi mumkin" deydi:

Direktiva Nimani boshqaradi
default-src Alohida yozilmagan hamma tur uchun zaxira
script-src, style-src Skriptlar va stillar
img-src, font-src, media-src Rasm, shrift, audio/video
connect-src fetch, WebSocket, sendBeacon
worker-src, manifest-src Worker va SW, PWA manifest
object-src, base-uri, form-action Plaginlar, <base>, forma manzili
frame-ancestors Sahifamizni kim iframe'ga joylay oladi
require-trusted-types-for, trusted-types Trusted Types (oldingi dars)

Qiymatlar: 'self' (o'z origin'imiz), 'none' (hech narsa), aniq manzil (https://ilmhamroh.uz), 'nonce-…', 'sha256-…'. Qo'shtirnoqli so'zlar — kalit so'zlar, qo'shtirnoqsiz — manzil.

3.2 Saytimizning CSP'si — jonli

IlmHamroh sahifasi (natija oynasi ham) shunday CSP bilan keladi. Uning connect-src qismi:

text
connect-src 'self' https://ilmhamroh.uz https://plausible.io https://*.sentry.io https://cdn.jsdelivr.net

11-qismda "natija oynasida fetch faqat ilmhamroh.uz ga ishlaydi" degan edik (fetch asoslari). Sababi — shu qator. Tekshiramiz:

html
<script type="module">
  let violation = null;
  document.addEventListener("securitypolicyviolation", (event) => {
    violation = `${event.violatedDirective} → ${event.blockedURI}`;
  });

  const menu = await fetch("https://ilmhamroh.uz/api/mashq/menyu/1");
  console.log("mashq API:", (await menu.json()).nom);

  let failure = "";
  try {
    await fetch("https://example.com/");
  } catch (error) {
    failure = `${error.name}: ${error.message}`;
  }
  await new Promise((resolve) => setTimeout(resolve, 100));
  console.log("begona sayt:", failure);
  console.log("CSP hodisasi:", violation);
</script>

Konsolda:

text
mashq API: Osh
begona sayt: TypeError: Failed to fetch
CSP hodisasi: connect-src → https://example.com/

Mashq API ishladi. example.com ga so'rov esa umuman ketmadi — brauzer uni CSP bo'yicha to'xtatdi. fetch faqat umumiy Failed to fetch beradi (sabab sizdan yashirin), lekin securitypolicyviolation hodisasi qaysi qoida to'sganini aniq aytadi. Chrome konsolida esa qizil xabar:

text
Connecting to 'https://example.com/' violates the following Content Security Policy directive: "connect-src 'self' https://ilmhamroh.uz https://plausible.io https://*.sentry.io https://cdn.jsdelivr.net". The action has been blocked.

Tarjimasi: "https://example.com/ ga ulanish CSP'ning connect-src qoidasini buzadi. Amal bloklandi." connect-src — XSS'dan keyingi oxirgi to'siq: hujumchining kodi ishlab ketsa ham, o'g'irlagan ma'lumotini begona serverga yubora olmaydi.

3.3 Meta yoki HTTP sarlavha

CSP'ni ikki yo'l bilan berish mumkin: server sarlavhasi (Content-Security-Policy:) yoki HTML'dagi <meta http-equiv>. Meta qulay (server sozlamasi kerak emas), lekin cheklangan. Biz Chrome 154 da sinadik:

text
The Content Security Policy directive 'frame-ancestors' is ignored when delivered via a <meta> element.
The Content Security Policy directive 'sandbox' is ignored when delivered via a <meta> element.
The report-only Content Security Policy 'script-src 'none'' was delivered via a <meta> element, which is disallowed. The policy has been ignored.

Ya'ni frame-ancestors, sandbox va "faqat xabar ber" rejimi (Content-Security-Policy-Report-Only) — faqat HTTP sarlavhada ishlaydi. Report-Only rejimi juda foydali: yangi CSP'ni avval shu rejimda qo'yasiz, u hech narsani to'smaydi, faqat buzilishlarni xabar qiladi. Hammasi toza bo'lgach — haqiqiy sarlavhaga o'tkazasiz.

3.4 Clickjacking va frame-ancestors

Hujumchi sizning saytingizni o'z sahifasida shaffof iframe ichida ochadi va ustiga "Sovg'ani olish" tugmasini qo'yadi. Mehmon uni bosadi — aslida esa sizning saytingizdagi "Hisobni o'chirish" ni. Bu clickjacking (iframe xavfsizligi). Himoya — frame-ancestors 'none' (hech kim joylay olmaydi) yoki 'self'. Eski brauzerlar uchun X-Frame-Options: DENY sarlavhasi. Ikkalasi ham faqat server sarlavhasida.

Tekshirib ko'ring: Sahifada <meta> bilan shunday CSP bor: default-src 'self'; frame-ancestors 'none'. Hujumchi sahifani o'z saytida iframe'ga joyladi. Sahifa ochiladimi?

Javob

Ha, ochiladi. frame-ancestors <meta> da e'tiborsiz qoldiriladi — Chrome konsolda shu haqda ogohlantiradi, xolos. default-src 'self' esa sizning sahifangiz nimani yuklashini boshqaradi, sizni kim joylashini emas. Clickjacking'dan himoya uchun frame-ancestors HTTP sarlavhasida yuborilishi kerak.

4. Fayl va kanalning yaxlitligi

4.1 SRI: begona fayl o'zgarmaganmi?

HTML darajasidagi xavfsizlik darsida <script integrity> ni ko'rgan edik: brauzer faylning hash'ini hisoblab, kutilgan bilan solishtiradi. Request, Response va fetch opsiyalari darsida esa fetch ning ham integrity opsiyasi borligini aytgan edik. Mana u:

html
<script type="module">
  const url = "https://ilmhamroh.uz/api/mashq/menyu/1";
  const good = "sha256-dN9tXb46hIKpWHBUOeNbRMZBPOOezsqvRyH9/0GE2ro=";
  const bad = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";

  const res = await fetch(url, { integrity: good });
  console.log("to'g'ri hash:", (await res.json()).nom);
  try {
    await fetch(url, { integrity: bad });
  } catch (error) {
    console.log("noto'g'ri hash:", error.name, error.message);
  }
</script>

Konsolda:

text
to'g'ri hash: Osh
noto'g'ri hash: TypeError Failed to fetch

To'g'ri hash'ni biz javobning baytlaridan Node'da hisobladik ({"id":1,"nom":"Osh",...} ning SHA-256 i). Noto'g'risida Chrome javobni oldi, hisobladi va rad etdi: SRI's integrity checks failed ("SRI yaxlitlik tekshiruvi o'tmadi"). Server javobi bir bayt o'zgarsa ham shunday bo'ladi — shuning uchun SRI faqat o'zgarmaydigan fayllar uchun: aniq versiyali CDN fayllari.

4.2 Secure context va mixed content

Ba'zi API'lar faqat xavfsiz kontekstda (secure context) ishlaydi: Service Worker (Service Worker hayot sikli), navigator.clipboard.readText, joylashuv, crypto.subtle. Xavfsiz kontekst — https:// sahifa yoki localhost / 127.0.0.1 (dasturchi qulayligi uchun istisno). Tekshirish: isSecureContext. Natija oynasida u true — ota sahifa HTTPS.

Nega? http:// sahifani yo'ldagi har kim (kafe Wi-Fi'si) o'zgartira oladi. Kuchli API'ni bunday sahifaga berish — uni hujumchiga berish. Shu sababli HTTPS sahifa ichidagi http:// skript ham bloklanadi — mixed content (HTML darajasidagi xavfsizlik).

5. Cross-origin isolation: COOP va COEP

5.1 Nega "to'liq ajratish" kerak?

Performansni o'lchash darsida 2018 yildagi Spectre hujumlarini eslagan edik: protsessor ichidagi mayda vaqt farqlarini o'lchab, xuddi shu jarayondagi boshqa saytning xotirasini o'qishga urinish. Brauzerlar javob berdi: aniq taymerlarni qo'pollashtirdi va xavfli imkoniyatlarni yopdi. Masalan, SharedArrayBuffer — bir nechta thread bitta xotirani bo'lishadi va undan juda aniq "soat" yasash mumkin.

Bu imkoniyatlar faqat cross-origin isolated (boshqa origin'lardan to'liq ajratilgan) sahifaga qaytariladi. Buning uchun sahifa ikki sarlavha yuboradi:

text
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
  • COOP (Cross-Origin-Opener-Policy) — sahifa ochgan yoki uni ochgan begona oynalar bilan bog'lanmaydi (window.opener uziladi). Sahifa o'z "guruhida" yolg'iz qoladi.
  • COEP (Cross-Origin-Embedder-Policy) — sahifa yuklaydigan har bir begona fayl (rasm, skript) o'zi "meni joylash mumkin" deb aytishi kerak: CORS yoki Cross-Origin-Resource-Policy sarlavhasi bilan. Aytmaganlar yuklanmaydi.

5.2 Sinab ko'rdik

Bitta sahifani ikki xil sarlavha bilan, Live Server kabi lokal serverda (127.0.0.1) ochdik:

Sarlavhalar crossOriginIsolated SharedArrayBuffer
Yo'q false undefined
COOP + COEP true function

Natija oynasida — false: sayt bu sarlavhalarni yubormaydi. Shu sababli SharedArrayBuffer va Atomics darsini natija oynasida emas, Live Server'da o'rgandik. Izolyatsiya yana nimani ochadi? performance.now() aniqligi 100 dan 5 mikrosekundgacha oshadi, xotirani o'lchaydigan performance.measureUserAgentSpecificMemory() paydo bo'ladi (biz tekshirdik: oddiy sahifada undefined, izolyatsiyalangan sahifada — funksiya).

Narxi: COEP bilan sahifangizga begona rasm, video, reklama yuklash qiyinlashadi — har biri CORS yoki CORP bilan kelishi kerak. Shuning uchun izolyatsiyani faqat haqiqatan kerak bo'lganda yoqishadi (video muharrir, o'yin, WebAssembly ilova).

6. sandbox va Permissions-Policy: imkoniyatlarni cheklash

6.1 sandbox: iframe'ning qafasi

iframe xavfsizligi darsida sandbox atributini ko'rgan edik: u iframe'ga hamma narsani taqiqlaydi, keyin allow-… bayroqlari bilan kerakli narsalarni qaytaradi. Natija oynasi:

html
<iframe sandbox="allow-scripts allow-forms allow-downloads"
        allow="clipboard-write; fullscreen" srcdoc="…"></iframe>
Bayroq Natija oynasida Shuning uchun
allow-scripts Bor JavaScript ishlaydi
allow-forms Bor Formalar (sayt ularni yuborilmagan holda "tekshiradi")
allow-downloads Bor <a download> bilan fayl yuklab olish
allow-same-origin Yo'q origin: null, sayt xotirasiga yo'l yo'q
allow-popups Yo'q window.open ishlamaydi

window.open ni sinab ko'rdik — u null qaytardi, Chrome konsolida esa: Blocked opening 'https://example.com/' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set. Tarjimasi: "yangi oyna ochish to'sildi: so'rov allow-popups ruxsati berilmagan sandbox iframe'dan keldi".

Diqqat: allow-scripts va allow-same-origin ni birga bermang (agar iframe ichidagi kod sizning origin'ingizdan bo'lsa). Bu ikkalasi bilan iframe ichidagi skript o'z sandbox atributini olib tashlab, qafasdan chiqib ketishi mumkin. Natija oynasiga ikkinchisi ataylab berilmagan.

6.2 Permissions-Policy: kamera, joylashuv, mikrofon

Permissions-Policy — sahifa va uning iframe'lari qaysi qurilma imkoniyatlarini ishlata olishini belgilaydigan sarlavha. IlmHamroh sahifasi:

text
Permissions-Policy: camera=(), geolocation=(), microphone=(self)

() — "hech kimga", (self) — "faqat o'z origin'imizga". Iframe'ga esa allow atributi orqali alohida beriladi — natija oynasiga faqat clipboard-write va fullscreen. Chrome'da buni sahifa ichidan tekshirish mumkin (document.featurePolicy — eski nom bilan qolgan, faqat Chromium'da):

html
<script>
  const policy = document.featurePolicy;
  for (const feature of ["clipboard-write", "fullscreen",
    "geolocation", "camera", "microphone"]) {
    console.log(feature, policy.allowsFeature(feature));
  }
  navigator.geolocation.getCurrentPosition(
    () => console.log("joylashuv olindi"),
    (error) => console.log("joylashuv:", error.message),
  );
</script>

Konsolda:

text
clipboard-write true
fullscreen true
geolocation false
camera false
microphone false
joylashuv: Geolocation has been disabled in this document by permissions policy.

Mikrofon sahifaning o'zida (self) ruxsat etilgan, lekin iframe'ning allow ida yo'q — natija oynasida false. Tarjimasi (oxirgi qator): "Bu hujjatda joylashuv permissions policy tomonidan o'chirilgan." Shuning uchun Permissions, Notifications va Geolocation darsida joylashuvni natija oynasida emas, Live Server'da o'rgandik. Sizning saytingizda esa bu sarlavha himoya: reklama iframe'i yoki begona skript mehmonning kamerasini so'ray olmaydi.

Permissions-Policy sarlavhasi va allow atributi Chrome va Edge'da to'liq; Firefox va Safari ularning faqat bir qismini qo'llaydi — Baseline emas (web-features, 2026-oktabr).

6.3 Hammasi birga

Natija oynasidagi kodingiz bir vaqtda shu devorlarning hammasi ichida ishlaydi. Diagrammada har bir devor va u nimani yopishi:

flowchart TD
  K["Siz yozgan kod"] --> S["sandbox:<br/>origin null"]
  S --> SO["Same-origin:<br/>sayt DOM'i yopiq"]
  S --> P["Popup yo'q"]
  K --> C["CSP: connect-src,<br/>script-src"]
  K --> PP["Permissions-Policy:<br/>kamera, joylashuv yo'q"]
  K --> I["COOP/COEP yo'q:<br/>SharedArrayBuffer yo'q"]
  K --> SC["Secure context:<br/>HTTPS — bor"]

Shuning uchun IlmHamroh sizga istalgan kodni ishga tushirishga ruxsat bera oladi: kod qafasdan tashqariga — sizning akkauntingizga, tokeningizga, kamerangizga — chiqa olmaydi.

Tekshirib ko'ring: Natija oynasida navigator.mediaDevices.getUserMedia({ video: true }) chaqirsangiz, brauzer kamera ruxsatini so'raydimi? Qaysi devor javob beradi?

Javob

So'ramaydi — so'rov darhol rad etiladi. Biz Chrome 154 da sinadik: SecurityError: Invalid security origin ("xavfsizlik origin'i yaroqsiz"). Birinchi bo'lib sandbox devori ishladi: null origin'ga brauzer kamerani umuman bermaydi. Bu devor bo'lmaganda ham Permissions-Policy to'xtatardi: sayt sarlavhasida camera=() ("hech kimga"), iframe'ning allow ida ham kamera yo'q. Ikki devor bitta joyni qo'riqlaydi — shuning uchun kamera darsini natija oynasida emas, Live Server'da o'rgandik.

Hujumchi nigohi

Faraz qiling, kelajakda kimdir vazifalar ga innerHTML qo'shdi va XSS teshigi ochildi. Hujumchi vazifa matniga kod yozdi. Bu darsdagi CSP va Trusted Types bilan nima bo'ladi?

  1. <script> matni va onerror atributi — script-src 'self' inline kodni to'xtatadi.
  2. innerHTML = satr ning o'zi — Trusted Types TypeError beradi, sink'ka satr tushmaydi.
  3. Kod qandaydir ishlab ketsa ham, ma'lumotni fetch("https://hujumchi…") bilan yubora olmaydi — connect-src. Rasm orqali yuborish (new Image().src = …?token=) — img-src 'self'.
  4. Sahifani o'z iframe'ida ochib, clickjacking qilish — bunga qarshi frame-ancestors kerak, lekin u meta'da ishlamaydi. Bu ochiq qolgan joy, TEXNIK-QARZ da yozilgan.

Kanon tekshiruvi aynan shu hujumlarni brauzerda sinaydi — natijalar Vazifalar qadamida.

7. Ko'p uchraydigan xatolar

7.1 'unsafe-inline' bilan "tuzatish"

CSP sahifani buzdi, Sardor script-src ga 'unsafe-inline' qo'shdi — hammasi ishladi. Va XSS himoyasi butunlay yo'qoldi. Tuzatish: inline kodni alohida faylga chiqarish yoki nonce/hash.

7.2 Sinamasdan qattiq CSP

To'lov vidjeti, shrift yoki analitika to'satdan ishlamay qoladi. Tuzatish: avval Content-Security-Policy-Report-Only (sarlavhada), buzilishlarni yig'ib, keyin yoqish.

7.3 frame-ancestors ni meta'ga yozish

U e'tiborsiz qoldiriladi va siz "himoyalangan" deb o'ylaysiz. Tuzatish: server sarlavhasi (Netlify _headers, nginx).

7.4 connect-src * yoki https:

"Hamma HTTPS manzilga" — hujumchi serveri ham HTTPS. Tuzatish: aniq manzillar ro'yxati.

7.5 allow-scripts allow-same-origin birga

O'z origin'ingizdagi kodni bunday iframe'da ishlatish — sandbox ni yo'qqa chiqaradi. Tuzatish: begona kodni alohida domen yoki null origin'da ishlatish (natija oynasi kabi).

8. Mashqlar

1-mashq (oson): CSP'ni o'qing

text
default-src 'self'; img-src 'self' https:; connect-src 'self' https://ilmhamroh.uz; object-src 'none'

Shu CSP'li sahifada:

  • https://cdn.jsdelivr.net/npm/dayjs skripti yuklanadimi?
  • https://example.com/osh.jpg rasmi ko'rinadimi?
  • fetch("https://ilmhamroh.uz/api/mashq/menyu") ishlaydimi?
Yechim
  • Skript — yo'q: script-src yozilmagan, demak default-src 'self' ishlaydi — faqat o'z origin.
  • Rasm — ha: img-src da https: — istalgan HTTPS manzil.
  • fetch — ha: connect-src da aynan shu domen bor.

default-src — "zaxira": alohida direktivasi yo'q turlarga qo'llanadi.

2-mashq (o'rta): «Bahor» menyu sahifasi uchun CSP

Natija oynasida meta CSP bilan sahifa yasang: skriptlar faqat sahifa ichidan ('unsafe-inline' — faqat shu mashq uchun, chunki natija oynasida tashqi fayl yo'q), fetch faqat https://ilmhamroh.uz ga. Ikki so'rov yuboring: mashq API'siga va https://example.com/ ga. Konsolga natijalar chiqsin.

Yechim
html
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Security-Policy"
        content="default-src 'none'; script-src 'unsafe-inline';
                 connect-src https://ilmhamroh.uz">
</head>
<body>
<script type="module">
  const res = await fetch("https://ilmhamroh.uz/api/mashq/menyu");
  console.log("menyu:", (await res.json()).length, "ta taom");
  try {
    await fetch("https://example.com/");
  } catch (error) {
    console.log("example.com:", error.message);
  }
</script>
</body>
</html>

Konsolda:

text
menyu: 4 ta taom
example.com: Failed to fetch

default-src 'none' — "boshqa hamma narsa taqiq", keyin kerakli ikkitasi ochildi. Bu yondashuv xavfsizroq: yangi resurs turi qo'shilsa, u avtomatik ruxsat olmaydi. Natija oynasida sizning meta CSP'ingiz saytning CSP'si ustiga qo'shiladi — ikkalasi ham bajariladi, ya'ni faqat torroq bo'lishi mumkin.

3-mashq (qiyin): Natija oynasi devorlari xaritasi

Natija oynasida bitta skript yozing. U quyidagi beshta savolga true/false javob chiqarsin: oyna o'z origin'igami ega (origin !== "null"), ota sahifaga kira oladimi, xavfsiz kontekstmi, SharedArrayBuffer bormi, popup ocha oladimi. Har savol — bitta qator.

Ishora: ota sahifaga kirishni try/catch bilan, popup'ni window.open(...) !== null bilan tekshiring.

Yechim
html
<script>
  function canReachParent() {
    try {
      return Boolean(parent.document);
    } catch {
      return false;
    }
  }

  const checks = {
    "o'z origin'i": origin !== "null",
    "ota sahifaga kirish": canReachParent(),
    "xavfsiz kontekst": isSecureContext,
    "SharedArrayBuffer": typeof SharedArrayBuffer === "function",
    "popup": window.open("https://example.com/") !== null,
  };
  for (const [name, value] of Object.entries(checks)) {
    console.log(`${name}: ${value}`);
  }
</script>

Konsolda:

text
o'z origin'i: false
ota sahifaga kirish: false
xavfsiz kontekst: true
SharedArrayBuffer: false
popup: false

Faqat bitta true — xavfsiz kontekst. Qolgan to'rttasi — devorlar: sandbox (origin va popup), same-origin policy (ota sahifa), izolyatsiya yo'qligi (SharedArrayBuffer). window.open to'silgani uchun Chrome konsolida qizil xabar ham chiqadi — shuning uchun bu misol "xato" belgili.

4-mashq: Vazifalar qadami — CSP va Trusted Types

13-qismning oxirgi qadami. vazifalar da sink yo'q (oldingi qadam) — endi brauzer ham buni kafolatlasin.

1. Branch va CSP (index.html, <head> boshida, charset dan keyin):

bash
git switch -c feature/csp
html
<meta http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'self';
               style-src 'self'; img-src 'self';
               connect-src 'self' https://ilmhamroh.uz;
               manifest-src 'self'; worker-src 'self';
               object-src 'none'; base-uri 'none';
               form-action 'self';
               require-trusted-types-for 'script';
               trusted-types vazifalar">

Har qator nega shunday:

  • script-src 'self' — faqat o'z fayllarimiz. HTML ichida skript yo'q edi: tema skripti (tema.js) matchMedia qadamida alohida faylga qo'yilgan. Shuning uchun 'unsafe-inline' kerak bo'lmadi. style-src 'self' ham shunday — style="" atributlari yo'q.
  • connect-src — o'zimiz va «Bahor» API'si. vendor/web-vitals.js ham o'z faylimiz — Performance API qadamida CDN o'rniga vendor nusxa tanlaganimizning sababi aynan shu qator.
  • manifest-src, worker-src — PWA manifesti va Service Worker.
  • base-uri 'none', object-src 'none', form-action 'self' — XSS'siz ham xavfli HTML hiylalariga qarshi.
  • Oxirgi ikki qator — Trusted Types, yagona ruxsat etilgan siyosat nomi vazifalar.

2. Trusted Types siyosati (asosiy.js). Kodda sink yo'q, lekin bitta joy TT talab qiladi: navigator.serviceWorker.register(url) — u skript manzilini oladi (TrustedScriptURL):

js
// Trusted Types (CSP: require-trusted-types-for 'script'): xavfli
// joylar (innerHTML, script.src, SW manzili...) oddiy satrni qabul
// qilmaydi, faqat siyosatdan o'tgan qiymatni. Bizga bittasi kerak —
// Service Worker manzili. Trusted Types bo'lmagan brauzerda — satr
const SW_MANZILI = "sw.js";
const siyosat = globalThis.trustedTypes?.createPolicy("vazifalar", {
  createScriptURL(url) {
    if (url !== SW_MANZILI) {
      throw new TypeError(`Ruxsat etilmagan skript manzili: ${url}`);
    }
    return url;
  },
});

// register ichida:
const manzil = siyosat?.createScriptURL(SW_MANZILI) ?? SW_MANZILI;

Siyosat faqat bitta manzilni — "sw.js" ni o'tkazadi, boshqasiga TypeError. ?. va ?? — Trusted Types bo'lmagan eski brauzerda oddiy satr ishlatiladi.

Manfiy nazorat: siyosatsiz register("sw.js") qilib ko'rdik — This document requires 'TrustedScriptURL' assignment. ("bu hujjat TrustedScriptURL talab qiladi") va Service Worker o'rnatilmadi. Ya'ni Trusted Types haqiqatan ishlayapti.

3. Hujjatlar. v4 yakunlandi — hujjatlar ham yangilanadi:

  • TEXNIK-QARZ.md — sarlavha v4; yangi qatorlar 11–17. Ular orasida: CSP meta'da, shuning uchun frame-ancestors va hisobot yo'q (13 — server sarlavhasiga o'tkazish 33-qismda), blocking="render" cheklovi (14), Web Vitals yig'ilmaydi (15), vendor nusxa (16).
  • AGENTS.md — 14 modul + tema.js, PWA, CSP; npm test — 90; yangi taqiqlar: sink'lar, CSP'ni yumshatish, QOBIQ/VERSIYA, vendor/ ni qo'lda tahrirlash.
  • README.md — v4, tekshiruv/ssenariy.md — qo'lda tekshirish ro'yxati (+27…36).

4. Tekshirish — brauzer 120/120 (CSP buzilishlari securitypolicyviolation bilan sanaldi):

text
✅ CSP: oddiy ishda buzilish 0 (hodisa va konsol): [[],[]]
✅ CSP: SW Trusted Types bilan o'rnatildi: true
✅ CSP hujum: innerHTML/insertAdjacentHTML — TypeError (Trusted Types): "TypeError"
✅ CSP hujum: <script> matni — TypeError: "TypeError"
✅ CSP hujum: script.src — TypeError: "TypeError"
✅ CSP hujum: begona fetch — to'sildi (connect-src): "TypeError"
✅ CSP hujum: begona rasm — to'sildi (img-src): "to'sildi"
✅ CSP hujum: hech narsa bajarilmadi: [null,null]
   buzilish turlari: connect-src, img-src, require-trusted-types-for

Birinchi qator eng muhimi: oddiy ishda (qo'shish, tema, dialog, eksport, SW, Web Vitals) — birorta ham buzilish yo'q. Qolganlari — «Hujumchi nigohi» dagi hujumlarning brauzerdagi isboti. Testlar 90/90.

Lighthouse 13.5.0 (mobil): 98 / 100 / 100 / 100. Best Practices'dagi csp-xss auditi bitta maslahat beradi: "The page contains a CSP defined in a <meta> tag. Consider moving the CSP to an HTTP header…" — CSP'ni HTTP sarlavhaga o'tkazing. GitHub Pages sarlavha qo'yishga ruxsat bermaydi — bu TEXNIK-QARZ 13-qatori.

5. Commit va PR. Sarlavha 72 belgidan oshmasin, tafsilot — tanada:

bash
git add index.html assets/js/asosiy.js TEXNIK-QARZ.md AGENTS.md \
  README.md tekshiruv/ssenariy.md
git commit -m "feat: CSP (meta) va Trusted Types" \
  -m "README, AGENTS.md, TEXNIK-QARZ v4 ga yangilandi"
gh pr create --fill
gh pr merge --merge

Diff: 6 fayl, +108 −20. vazifalar v4 tayyor.

9. Real ishda

  • Xavfsizlik sarlavhalari. Katta saytlar CSP, frame-ancestors, COOP, Permissions-Policy va HSTS ni server sozlamasida (nginx, Cloudflare) qo'yadi. HSTS (Strict-Transport-Security) — brauzerga "bu saytni bundan keyin faqat HTTPS bilan och" degan sarlavha. Ularni tekshirishning bepul yo'li — Mozilla HTTP Observatory. Server tomoni — backend va DevOps qismlarida.
  • Kod ishga tushiradigan servislar. CodePen, JSFiddle va IlmHamroh'ning natija oynasi — sandbox + alohida origin + CSP. Begona kodni xavfsiz bajarishning standart yo'li.
  • Izolyatsiya. Figma, Google Earth, brauzer o'yinlari va video muharrirlar SharedArrayBuffer uchun COOP/COEP yoqadi.
  • Intervyu. "Same-origin policy nimani to'xtatadi?", "CORS va CSP farqi?", "CSRF'dan qanday himoyalanasiz?", "SharedArrayBuffer nega hamma joyda ishlamaydi?" — frontend xavfsizlik savollari.

13-qism yakuni

Tabriklaymiz — 13-qismni tugatdingiz! Bu qism brauzerning JavaScript'ga beradigan asboblari, sahifaning tezligi va xavfsizligi haqida edi. Bosib o'tgan yo'l:

flowchart TD
  A["1–4: Kadr va kuzatuvchilar<br/>rAF, debounce, observer"] --> B["5–10: Foydalanuvchi va qurilma<br/>tema, bufer, dialog"]
  B --> C["11–18: Fayl va media<br/>Blob, Canvas, audio"]
  C --> D["19–23: Parallel va oflayn<br/>Worker, SW, PWA"]
  D --> E["24–26: Web Components<br/>Shadow DOM"]
  E --> F["27–30: Tezlik<br/>Web Vitals, DevTools"]
  F --> G["31–32: Xavfsizlik<br/>XSS, CSP"]
  A -. "qoralama" .-> V["vazifalar v4"]
  B -. "tema, dialog" .-> V
  C -. "eksport, import" .-> V
  D -. "oflayn, PWA" .-> V
  F -. "CLS 0" .-> V
  G -. "CSP" .-> V

Diagrammaga qarang: chapda — mavzular zanjiri, har biri oldingisiga tayanadi. Punktir chiziqlar — vazifalar qaysi bloklarda o'sgani. Faqat Web Components bloki ilovaga tegmadi — uni «Bahor» menyusida qurdik. Endi har blok haqida bir gap:

  1. Kadr va kuzatuvchilar (1–4). requestAnimationFrame — har kadrga bitta yangilash. Debounce va throttle — tez-tez keladigan hodisani siyraklashtirish. Intersection, Resize va Mutation kuzatuvchilari — brauzer o'zi "o'zgardi" deb xabar beradi, siz har kadrda so'ramaysiz.
  2. Foydalanuvchi va qurilma (5–10). matchMedia bilan tema va harakat sozlamasi, almashuv buferi, ruxsatlar va bildirishnomalar, navigator, <dialog> va Popover, Web Animations API.
  3. Fayl va media (11–18). File va Blob, faylni o'qish va yuklash, sudrab tashlash, Canvas 2D'da chizish va o'yin sikli, audio/video, Web Audio, kamera va mikrofon.
  4. Parallel va oflayn (19–23). Web Worker — og'ir hisob alohida thread'da; SharedArrayBuffer — umumiy xotira; Service Worker, kesh strategiyalari va o'rnatiladigan PWA.
  5. Web Components (24–26). O'z HTML tegingiz (custom element), Shadow DOM va komponentni tashqaridan stillash.
  6. Tezlik (27–30). Layout thrashing, Core Web Vitals (LCP, INP, CLS), asosiy thread'ni bo'shatish va DevTools profili. Asosiy qoida: avval o'lcha, keyin tuzat.
  7. Xavfsizlik (31–32). XSS: source va sink, sanitizatsiya, Trusted Types. Brauzer devorlari: same-origin, CSP, SameSite, COOP/COEP, sandbox, Permissions-Policy.

O'zingizni tekshiring — quyidagilarni qila olasizmi?

  • Animatsiyani requestAnimationFrame bilan yozib, qidiruv maydonini debounce bilan tinchlantira olaman.
  • Element ekranga chiqqanini scroll hodisasisiz, IntersectionObserver bilan bila olaman.
  • Faylni foydalanuvchidan olib o'qiy olaman va JavaScript'da yasalgan faylni yuklab bera olaman.
  • Og'ir hisobni Web Worker'ga, uzun siklni scheduler.yield() bilan bo'laklarga o'tkaza olaman.
  • Service Worker bilan sayt oflaynda ham ochiladigan qila olaman.
  • Sahifa nega sekinligini Performance profilidan topib, LCP, INP va CLS ni o'lchab ko'rsata olaman.
  • Kodda XSS sink'larini topa olaman va sahifaga CSP qo'ya olaman.

vazifalar ham shu qism bilan birga o'sdi. 12-qism oxirida u ishlardi va testlar bilan himoyalangan edi. Endi v4 da yozilayotgan matn qoralama bo'lib saqlanadi. Tizim temasi va o'chirish dialogi bor, ro'yxatni faylga eksport va fayldan import qilsa bo'ladi. Ilova oflayn ishlaydi va telefonga o'rnatiladi. Tezligi o'lchanadi, sakrash (CLS) tuzatildi, XSS sink'lari — 0, CSP va Trusted Types brauzer darajasida qo'riqlaydi.

Raqamlarda: Lighthouse (mobil) 98 / 100 / 100 / 100, 90 ta avtomatik test, brauzerda 120 ta tekshiruv. Qism boshida qo'yilgan maqsad — "Lighthouse ≥ 90, XSS va CSP himoyasi" — bajarildi.

Qaysidir band qiyin tuyulsa — o'sha darsga qayting. Endi kod nafaqat ishlaydi, balki tez va xavfsiz ishlaydi. 14-qismda keyingi savolga o'tamiz: qaysi yechim tezroq ekanini o'lchamasdan, oldindan qanday aytish mumkin? Bu — algoritmlar va Big-O.

Xulosa

  • Same-origin policy — asosiy devor: begona origin'ni o'qish taqiqlangan, joylash va yuborish — mumkin; CORS — server ruxsati bilan ochilgan eshik.
  • "Yuborish" ning xavfi — CSRF; cookie'da SameSite=Lax/Strict va server tekshiruvi himoya qiladi.
  • CSP — sahifaning o'z devori: direktivalar oilasi, 'self', aniq manzillar; frame-ancestors, sandbox va Report-Only faqat HTTP sarlavhada.
  • SRI — fayl o'zgarmaganligi, secure context — kuchli API'lar faqat HTTPS'da, COOP+COEP — SharedArrayBuffer va aniq taymerlar uchun to'liq izolyatsiya.
  • sandbox va Permissions-Policy imkoniyatlarni cheklaydi; natija oynasi — bularning hammasi birga ishlaydigan jonli misol.

Keyingi dars: Big-O notatsiyasi — 14-qism boshlanadi: algoritm qanchalik tez ekanini ma'lumot hajmi o'sganda baholash.

Manbalar

  • MDN: "Same-origin policy", "Content Security Policy (CSP)", "Cross-Origin-Opener-Policy", "Cross-Origin-Embedder-Policy", "Permissions-Policy", "Secure contexts" — developer.mozilla.org
  • web.dev: "Making your website cross-origin isolated using COOP and COEP", "Mitigate cross-site scripting (XSS) with a strict Content Security Policy" — web.dev
  • W3C: Content Security Policy Level 3, Subresource Integrity — w3.org/TR/CSP3, w3.org/TR/SRI
  • OWASP: "Cross-Site Request Forgery Prevention Cheat Sheet", "Clickjacking Defense Cheat Sheet" — cheatsheetseries.owasp.org
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Brauzer xavfsizlik modeli: same-origin, CSP, COOP/COEP, sandbox va Permissions-Policy — IlmHamroh