CSRF & XSS
XSS va CSRF — brauzer orqali amalga oshiriladigan ikki klassik hujum. Ikkalasi ham foydalanuvchining brauzeridan uning xabarisiz foydalanadi, lekin turli yo‘llar bilan:
| XSS | CSRF | |
|---|---|---|
| To‘liq nomi | Cross-Site Scripting | Cross-Site Request Forgery |
| Mohiyati | Hujumchi kodi sizning saytingizda ishlaydi | Hujumchi sayti sizning saytingizga so‘rov yuboradi |
| Nima qila oladi | Sahifadagi hamma narsani: tokenni o‘g‘irlash, amallar bajarish | Faqat so‘rov yuborish, javobni o‘qiy olmaydi |
| Asosiy himoya | Chiqishni ekranlash, CSP | SameSite cookie, Origin tekshiruvi, CSRF token |
XSS — saytga begona skript kiritish
Qanday ishlaydi?
Blog platformasida izoh qoldirish mumkin. Hujumchi oddiy matn o‘rniga quyidagini yozadi:
Server izohni bazaga saqlaydi va keyin sahifada ekranlamasdan ko‘rsatadi. Sahifani ochgan har bir foydalanuvchining brauzeri bu skriptni saytning o‘z kodi deb bajaradi. Skript localStoragedagi tokenni hujumchiga yuboradi.
XSS’ning uch turi bor:
- Stored (saqlangan) — zararli kod bazada saqlanadi va sahifani ochgan hammaga ko‘rsatiladi. Eng xavfli turi.
- Reflected (qaytarilgan) — kod URL parametrida keladi va darhol javobga qaytariladi:
/search?q=<script>...</script>. - DOM-based — kod serverga umuman bormaydi. Frontend JavaScript’i URL’dagi ma’lumotni xavfli usulda sahifaga qo‘shadi, masalan
innerHTMLorqali.
API nuqtai nazaridan
JSON qaytaradigan API’ning o‘zi odatda HTML yaratmaydi. Lekin uning ma’lumotlarini frontend sahifaga chiqaradi. Shuning uchun himoya ikki tomonda bo‘ladi:
Frontend — ma’lumotni HTML sifatida emas, matn sifatida chiqaradi: textContent ishlatiladi, innerHTML emas. React va Vue kabi framework’lar standart holatda shunday qiladi.
API — quyidagi qoidalarga amal qiladi.
1. To‘g‘ri Content-Type
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Content-Type-Options", "nosniff")
Content-Type ko‘rsatilmasa, Go javob turini tananing birinchi baytlariga qarab aniqlaydi. JSON ichida <html> bilan boshlanadigan satr bo‘lsa, javob text/html deb belgilanishi mumkin. Keyin brauzer uni sahifa sifatida ochadi va ichidagi skriptni bajaradi.
X-Content-Type-Options: nosniff brauzerga Content-Typeni taxmin qilmasdan, aynan ko‘rsatilganidek qabul qilishni buyuradi.
2. JSON’dagi HTML belgilari
encoding/json standart holatda <, > va & belgilarini <, >, & ko‘rinishida kodlaydi. Bu JSON HTML sahifa ichiga joylansa ham, u yerda </script> teglari paydo bo‘lishining oldini oladi. Bu himoyani o‘chirmang. SetEscapeHTML(false) faqat aniq sabab bo‘lganda ishlatiladi.
3. HTML yaratilsa — faqat html/template
Server HTML sahifa yoki email shablon yaratayotgan bo‘lsa, text/template emas, html/template paketi ishlatiladi. U kontekstga qarab avtomatik ekranlaydi:
=== text/template (XAVFLI) ===
<p>Izoh: <script>alert("XSS")</script></p>
<a href="javascript:alert(1)">Profil</a>
<script>var name = "; alert(1); //;</script>
=== html/template (XAVFSIZ) ===
<p>Izoh: <script>alert("XSS")</script></p>
<a href="#ZgotmplZ">Profil</a>
<script>var name = "\"; alert(1); //";</script>
html/template har bir joy uchun alohida qoida qo‘lladi:
- HTML matni ichida
<va>HTML entity’larga aylantirildi, skript bajarilmaydi; hrefichidagi xavflijavascript:URL’i#ZgotmplZbilan almashtirildi;<script>ichida qiymat to‘g‘ri JavaScript satriga aylantirildi.
template.HTML turi ekranlashni o‘chiradi. Uni faqat ishonchli manbadan kelgan HTML uchun ishlating, foydalanuvchi kiritgan ma’lumot uchun hech qachon ishlatmang.
4. Content Security Policy (CSP)
CSP — brauzerga sahifada qaysi manbalardan skript, stil va rasm yuklash mumkinligini aytadigan sarlavha:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'
XSS orqali sahifaga <script> kiritilgan taqdirda ham, CSP inline skriptlarni va begona domenlardan yuklanadigan skriptlarni bloklaydi. Bu ikkinchi himoya qatlami. Faqat JSON qaytaradigan API uchun eng qat’iy variant yetarli: default-src 'none'; frame-ancestors 'none'. Sarlavhalar Security headers & CORS darsida batafsil ko‘riladi.
CSRF — foydalanuvchi nomidan soxta so‘rov
Qanday ishlaydi?
Aziza bank saytiga kirgan. Brauzerda bank.uz uchun session cookie saqlangan. Keyin u boshqa oynada zararli saytni ochadi. U saytda yashirin forma bor:
<form action="https://bank.uz/transfer" method="POST" id="f">
<input name="to" value="hacker-hisobi">
<input name="amount" value="1000000">
</form>
<script>document.getElementById('f').submit()</script>
Brauzer bank.uzga POST so‘rov yuboradi va unga avtomatik ravishda Azizaning cookie’sini qo‘shadi. Server cookie’ni ko‘rib, so‘rovni Azizaniki deb o‘ylaydi va pulni o‘tkazib yuboradi.
Hujumchi javobni o‘qiy olmaydi. Lekin unga bu kerak ham emas, chunki amalning o‘zi bajarildi.
Kimga xavfli?
CSRF faqat brauzer autentifikatsiya ma’lumotini avtomatik yuboradigan holatda ishlaydi:
| Autentifikatsiya | CSRF xavfi |
|---|---|
| Cookie (session yoki JWT cookie’da) | ⚠️ Bor |
| HTTP Basic auth | ⚠️ Bor |
Authorization: Bearer sarlavhasi (JavaScript qo‘shadi) |
✅ Yo‘q. Boshqa sayt bu sarlavhani qo‘sha olmaydi |
Bizning API’miz tokenni Authorization sarlavhasida qabul qiladi. Shu sababli u CSRF’dan tabiiy ravishda himoyalangan. Lekin token cookie’da saqlansa, himoya kerak bo‘ladi.
Himoya 1: SameSite cookie
http.SetCookie(w, &http.Cookie{
Name: "session_id",
Value: id,
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteLaxMode,
})
SameSite=Lax bo‘lsa, brauzer boshqa saytdan kelgan POST, PUT va DELETE so‘rovlarga cookie qo‘shmaydi. Zamonaviy brauzerlarda bu CSRF’ning asosiy qismini to‘xtatadi.
Lekin SameSite yagona himoya bo‘lib qolmasligi kerak. U subdomenlar o‘rtasidagi so‘rovlarni to‘xtatmaydi, chunki evil.example.uz va api.example.uz brauzer uchun bir xil "sayt" hisoblanadi. Eski brauzerlar esa uni umuman qo‘llab-quvvatlamasligi mumkin.
Himoya 2: http.CrossOriginProtection (Go 1.25+)
Go 1.25 versiyasida net/http paketiga CSRF’dan himoyalovchi tayyor middleware qo‘shildi. U boshqa manbadan kelgan xavfli so‘rovlarni brauzer yuboradigan sarlavhalar yordamida aniqlaydi:
Sec-Fetch-Site— so‘rov qayerdan kelganini bildiradi. Zamonaviy brauzerlarning barchasi uni yuboradi;- u bo‘lmasa,
OriginsarlavhasiHostbilan solishtiriladi.
GET, HEAD va OPTIONS xavfsiz metodlar hisoblanadi, shuning uchun ular doim o‘tkaziladi. Bu metodlar holatni o‘zgartirmasligi kerak.
shu saytdan → 200
begona saytdan → 403
eski brauzer, begona Origin → 403
ishonchli frontend → 200
curl yoki mobil ilova → 200
- Boshqa saytdan kelgan so‘rovlar
403bilan rad etildi. - Ishonchli ro‘yxatdagi frontend domeni o‘tkazildi.
- Sarlavhasiz so‘rovlar o‘tkazildi. Ular brauzerdan emas,
curl, mobil ilova yoki boshqa serverdan kelgan deb hisoblanadi. Bunday klientlar cookie’ni avtomatik yubormaydi, shuning uchun CSRF ular uchun xavf tug‘dirmaydi.
CrossOriginProtection ichki holatga ega emas va tokenlar talab qilmaydi. Shuning uchun uni ulash oson.
Himoya 3: CSRF token
An’anaviy usul — har bir forma yoki sessiya uchun tasodifiy token:
- Server tasodifiy token yaratadi va uni sahifaga yoki cookie’ga joylaydi.
- Frontend har bir
POSTso‘rovda tokenni sarlavhada yuboradi:X-CSRF-Token: .... - Server tokenni tekshiradi.
Boshqa sayt tokenni bilmaydi, chunki u sahifani o‘qiy olmaydi. Shu sababli to‘g‘ri so‘rov yasay olmaydi. Bu usul eng keng qo‘llab-quvvatlanadi, lekin frontend va backend’da qo‘shimcha kod talab qiladi. Go 1.25+ da ko‘pchilik holatlar uchun CrossOriginProtection va SameSite birgalikda yetarli.
Himoya 4: Content-Type tekshiruvi
Boshqa sayt HTML forma orqali faqat application/x-www-form-urlencoded, multipart/form-data yoki text/plain turidagi so‘rovni oldindan ruxsat so‘ramasdan (CORS preflight’siz) yubora oladi. API faqat application/json qabul qilsa va buni qat’iy tekshirsa, forma orqali soxta so‘rov yuborib bo‘lmaydi.
Bu qo‘shimcha qatlam, asosiy himoya emas.
Xulosa
- XSS — hujumchi skripti sizning sahifangizda ishlaydi. CSRF — hujumchi sayti sizning API’ngizga foydalanuvchi nomidan so‘rov yuboradi.
- API’da XSS’dan himoya: to‘g‘ri
Content-Type,nosniff,encoding/jsonekranlashi, HTML uchun faqathtml/templateva CSP. html/templatema’lumotni kontekstga qarab avtomatik ekranlaydi.text/templateekranlamaydi.- CSRF faqat cookie kabi avtomatik yuboriladigan autentifikatsiyada xavfli.
Authorization: Bearersarlavhasi undan himoyalangan. - Cookie ishlatilsa:
SameSite,http.CrossOriginProtectionva kerak bo‘lsa CSRF token.
Keyingi darsda kiruvchi ma’lumotni tozalash va xavfsiz ishlatish usullarini ko‘ramiz.