Veb
CSRF va SameSite cookie: foydalanuvchi nomidan yuborilgan so'rovlar
CSRF qanday ishlaydi, SameSite cookie undan qanchalik himoya qiladi, CSRF token, cookie va bearer token'li API'lar hamda CORS bilan bog'liqlik. Laravel va Node misollari bilan.
· 9 daq. o'qish

Cross-Site Request Forgery (CSRF) — foydalanuvchi o'zi bilmagan holda, o'z sessiyasi bilan sizning saytingizga so'rov yuborib qo'yadigan hujum. Foydalanuvchi sizning tizimingizga kirgan, keyin boshqa sahifani ochgan. O'sha sahifa yashirin forma orqali sizning saytingizga POST yuboradi. Brauzer esa odatiga ko'ra so'rovga sizning saytingiz cookie'larini qo'shadi — va server buni haqiqiy foydalanuvchi amali deb qabul qiladi.
So'nggi yillarda brauzerlar SameSite cookie atributini joriy qilgani sababli CSRF ancha qiyinlashdi. Lekin "endi CSRF yo'q" degan xulosa noto'g'ri. Ushbu maqolada CSRF qanday ishlashini, SameSite nimani yopadi va nimani yopmasligini, tokenlar, API'lar va CORS o'rtasidagi bog'liqlikni ko'rib chiqamiz.
Hujum qanday ko'rinadi
Tasavvur qiling, ilovangizda email manzilni o'zgartirish endpoint'i bor:
POST /profile/email
Cookie: session=...
email=new@example.uz
Hujumchi o'z sahifasiga quyidagini joylashtiradi:
<form action="https://app.example.uz/profile/email" method="POST" id="f">
<input type="hidden" name="email" value="attacker@evil.example">
</form>
<script>document.getElementById('f').submit();</script>
Agar foydalanuvchi tizimga kirgan bo'lsa va server faqat sessiya cookie'siga tayansa, email almashadi. Keyin hujumchi "parolni tiklash" orqali akkauntni egallaydi. Xuddi shu usul bilan pul o'tkazish, rol o'zgartirish, ma'lumot o'chirish kabi amallarni bajarish mumkin.
E'tibor bering: hujumchi javobni o'qiy olmaydi. CSRF — "ko'r" hujum, uning maqsadi ma'lumot o'g'irlash emas, balki holatni o'zgartirish.
Nima uchun bu ekspertiza uchun muhim
CSRF CWE-352 sifatida tasniflanadi va OWASP Top 10 (2021) da A01 "Broken Access Control" toifasiga kiritilgan. OWASP ASVS esa holatni o'zgartiruvchi so'rovlar uchun CSRF himoyasini alohida talab qiladi. Ekspertizada odatda quyidagilar tekshiriladi:
- Holatni o'zgartiruvchi formalarda CSRF token bormi va server uni haqiqatan tekshiradimi.
- Sessiya cookie'larida
SameSite,Secure,HttpOnlyatributlari o'rnatilganmi. GETso'rovi orqali holat o'zgarmaydimi.- CORS sozlamalari begona domenga cookie bilan so'rov yuborib, javobni o'qishga ruxsat bermaydimi.
SameSite: nimani yopadi, nimani yopmaydi
SameSite atributi brauzerga cookie'ni boshqa saytdan boshlangan so'rovlarga qo'shish-qo'shmaslikni aytadi:
- Strict — cookie faqat o'z saytingiz ichidagi so'rovlarda yuboriladi. Boshqa saytdagi havoladan kelganda ham foydalanuvchi "kirilmagan" holatda bo'ladi.
- Lax — boshqa saytdan kelgan oddiy navigatsiyada (havola orqali
GET) cookie yuboriladi, lekinPOSTformalar,fetch,iframeva rasmlarda yuborilmaydi. - None — cookie hamma joyda yuboriladi. Bu holda
Securemajburiy.
Zamonaviy brauzerlarning ko'pchiligi atribut ko'rsatilmagan cookie'ni Lax deb hisoblaydi. Laravel ham sessiya cookie'si uchun sukut bo'yicha lax ishlatadi (config/session.php dagi same_site).
Lax klassik POST CSRF'ni yopadi. Ammo u to'liq himoya emas:
- GET orqali holat o'zgarishi. Agar
/logout,/delete?id=5yoki/approve?id=7GETbilan ishlasa,Laxcookie yuboradi va hujum ishlaydi. - "Site" va "origin" farqi. SameSite sayt darajasida ishlaydi:
app.example.uzvablog.example.uzbir sayt hisoblanadi. Agar subdomenlardan birida XSS bo'lsa yoki u boshqa tomonga topshirilgan bo'lsa, u yerdan yuborilgan so'rov "same-site" bo'ladi va SameSite yordam bermaydi. SameSite=Nonekerak bo'lgan holatlar. Ilova boshqa saytga iframe ichida joylashtirilsa yoki uchinchi tomon integratsiyasi bo'lsa, cookieNonega o'tkaziladi va himoya yo'qoladi.- Eski brauzerlar va maxsus mijozlar atributni har doim bir xil talqin qilmaydi.
SameSite — yaxshi qo'shimcha qatlam, lekin CSRF token'ning o'rnini bosmaydi.
CSRF token: asosiy himoya
Klassik himoya — synchronizer token: server sessiyaga tasodifiy token yozadi, har bir formaga uni yashirin maydon sifatida qo'shadi va har bir holatni o'zgartiruvchi so'rovda tekshiradi. Begona sayt bu tokenni bilmaydi va o'qiy olmaydi.
Laravel
Laravel'da CSRF himoyasi web middleware guruhida sukut bo'yicha yoqilgan. Blade formalarida:
<form method="POST" action="/profile/email">
@csrf
<input type="email" name="email">
</form>
Axios va Inertia XSRF-TOKEN cookie'sini o'qib, X-XSRF-TOKEN headerida avtomatik yuboradi. Tekshirish kerak bo'lgan asosiy joy — istisnolar ro'yxati. Laravel 11+ da bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'webhooks/payment', // faqat haqiqiy tashqi webhook'lar
]);
})
Istisnolarga faqat tashqi xizmatlar chaqiradigan webhook'larni qo'shing va ularni imzo (HMAC) bilan tekshiring. "Ishlamayapti, shuning uchun istisnoga qo'shdim" degan 'api/*' yoki '*' — keng tarqalgan va jiddiy xato.
Node (Express)
Ilgari keng ishlatilgan csurf paketi eskirgan deb belgilangan. Uning o'rniga double-submit cookie naqshini amalga oshiradigan kutubxonalardan foydalaning yoki minimal himoyani o'zingiz yozing: Origin headerini tekshirish va token.
const ALLOWED_ORIGINS = new Set(['https://app.example.uz']);
function verifyOrigin(req, res, next) {
if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) return next();
const origin = req.get('Origin') || '';
if (!ALLOWED_ORIGINS.has(origin)) {
return res.status(403).json({ error: 'Invalid origin' });
}
next();
}
app.use(verifyOrigin);
Origin tekshiruvi zamonaviy brauzerlarda yaxshi ishlaydi, chunki POST so'rovlarida brauzer bu headerni o'zi qo'yadi va JavaScript uni soxtalashtira olmaydi. Qo'shimcha ravishda Sec-Fetch-Site headeridan ham foydalanish mumkin: cross-site qiymatli holatni o'zgartiruvchi so'rovlarni rad eting.
Sessiya cookie'si uchun:
app.use(session({
secret: process.env.SESSION_SECRET,
cookie: { httpOnly: true, secure: true, sameSite: 'lax' },
}));
API'lar: cookie yoki bearer token
CSRF'ning ildizi — brauzer cookie'ni avtomatik qo'shishi. Shuning uchun API'da autentifikatsiya qanday qilinishi hal qiluvchi:
- Bearer token (
Authorization: Bearer ...) — brauzer bu headerni o'zi qo'shmaydi, uni JavaScript qo'yishi kerak. Begona sayt tokenni bilmaydi, demak CSRF amalda mumkin emas. Lekin tokenlocalStorageda saqlansa, XSS uni o'g'irlashi mumkin — bu boshqa xavf. - Cookie asosidagi API (SPA, Sanctum stateful) — brauzer cookie'ni avtomatik yuboradi, demak CSRF himoyasi kerak. Laravel Sanctum SPA rejimida shuning uchun avval
/sanctum/csrf-cookiechaqiriladi va keyingi so'rovlarX-XSRF-TOKENbilan yuboriladi.
Sanctum'da SANCTUM_STATEFUL_DOMAINS ro'yxatiga faqat o'z frontend domenlaringizni yozing. Mobil ilova uchun esa cookie emas, token rejimidan foydalaning.
Bir xato tez-tez uchraydi: API "JSON qabul qiladi, demak forma bilan hujum qilib bo'lmaydi" deb CSRF tekshiruvi o'chiriladi. Agar server Content-Type ni qat'iy tekshirmasa va text/plain yoki application/x-www-form-urlencoded tanasini ham JSON sifatida o'qisa, oddiy forma bilan hujum qilish mumkin bo'lib qoladi.
CORS bilan bog'liqlik
CORS va CSRF ko'pincha chalkashtiriladi. Muhim nuqtalar:
- CORS CSRF'dan himoya qilmaydi. CORS faqat begona sahifa javobni o'qishi mumkinmi, shuni boshqaradi. Oddiy so'rovlar (forma
POST,text/plain) preflight'siz yuboriladi va server ularni bajaradi — javob o'qilmasa ham. - Noto'g'ri CORS CSRF'ni kuchaytiradi. Agar server istalgan
Originni aks ettirib,Access-Control-Allow-Credentials: trueqaytarsa, begona sayt cookie bilan so'rov yuborib, javobni ham o'qiy oladi — jumladan, CSRF tokenni. Shunda token himoyasi ham yiqiladi. - Preflight foydali, lekin yagona himoya emas.
Content-Type: application/jsonyoki maxsus header preflight'ni majburlaydi va to'g'ri sozlangan CORS uni rad etadi. Lekin bu faqat serverContent-Typeni qat'iy tekshirsagina ishlaydi.
Laravel'da config/cors.php:
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_origins' => ['https://app.example.uz'],
'supports_credentials' => true,
allowed_origins ga * yozib, supports_credentials ni true qilish mumkin emas — buni to'g'ri sozlang.
O'zingiz qanday tekshirishingiz mumkin
Token haqiqatan tekshiriladimi
Brauzerda tizimga kiring, DevTools orqali holatni o'zgartiruvchi so'rovni "Copy as cURL" qiling, keyin tokenni olib tashlab qayta yuboring:
# Token bilan — 200/302 kutiladi
curl -si -X POST https://staging.example.uz/profile/email \
-H "Cookie: laravel_session=..." \
-d "_token=VALID&email=test@example.uz"
# Tokensiz — 419 (Laravel) yoki 403 kutiladi
curl -si -X POST https://staging.example.uz/profile/email \
-H "Cookie: laravel_session=..." \
-d "email=test@example.uz"
Ikkinchi so'rov muvaffaqiyatli bo'lsa, himoya ishlamayapti.
Origin va CORS
curl -si https://staging.example.uz/api/user \
-H "Origin: https://evil.example" \
-H "Cookie: laravel_session=..." | grep -i "access-control"
Javobda Access-Control-Allow-Origin: https://evil.example va Access-Control-Allow-Credentials: true birga chiqsa, bu jiddiy muammo.
Cookie atributlari
curl -si https://staging.example.uz/login | grep -i set-cookie
Sessiya cookie'sida Secure, HttpOnly va SameSite=Lax (yoki Strict) bo'lishi kerak.
GET bilan holat o'zgarishi
Marshrutlar ro'yxatini ko'rib chiqing:
php artisan route:list --method=GET | grep -iE "delete|remove|logout|approve|toggle"
Holatni o'zgartiruvchi amallar POST, PUT, PATCH yoki DELETE bo'lishi kerak.
Qisqa checklist
- Barcha holatni o'zgartiruvchi so'rovlar CSRF token yoki
Origintekshiruvi bilan himoyalangan. - CSRF istisnolari ro'yxatida faqat imzo bilan tekshiriladigan webhook'lar bor.
-
GETso'rovlari holatni o'zgartirmaydi. - Sessiya cookie'larida
Secure,HttpOnly,SameSite=LaxyokiStricto'rnatilgan. - Cookie asosidagi SPA/API uchun CSRF himoyasi yoqilgan, Sanctum stateful domenlari aniq ko'rsatilgan.
- Server
Content-Typeni qat'iy tekshiradi. - CORS'da
Originaks ettirilmaydi, credentials faqat aniq domenlar uchun. - Subdomenlar nazorat ostida, ularda XSS yo'qligi tekshirilgan.
Xulosa
SameSite cookie CSRF'ni ancha qiyinlashtirdi, lekin uni yo'q qilmadi. Ishonchli himoya bir necha qatlamdan iborat: CSRF token yoki Origin tekshiruvi, holatni faqat POST/PUT/DELETE orqali o'zgartirish, to'g'ri cookie atributlari va qat'iy CORS. Bu sozlamalar ko'pincha mavjud, lekin istisnolar ro'yxati yoki "vaqtincha" o'chirilgan tekshiruv tufayli ishlamay qoladi — ekspertiza aynan shunday joylarni topadi.
Formalaringiz va API'ingizdagi CSRF himoyasini ekspertizadan oldin tekshirmoqchimisiz? Skanerlash uchun ariza qoldiring — Claude AI agenti marshrutlar, middleware va cookie sozlamalarini ko'rib chiqadi, mutaxassisimiz esa topilgan teshiklarni yopishga yordam beradi.


