SameSite — brauzer xavfsizlik mexanizmi bo'lib, saytning cookie'lari boshqa saytlardan kelgan so'rovlarga qachon qo'shilishini belgilaydi. SameSite cheklovlari CSRF, cross-site leaks va ba'zi CORS ekspluatatsiyalari kabi turli cross-site hujumlardan qisman himoya qiladi.
2021-yildan Chrome, agar cookie chiqargan vebsayt o'z cheklov darajasini aniq belgilamagan bo'lsa, standart holatda Lax SameSite cheklovlarini qo'llaydi. Shu sabab bu cheklovlar qanday ishlashini va ularni qanday chetlab o'tish mumkinligini yaxshi tushunish muhim.
SameSite cheklovlari kontekstida sayt (site) — bu top-level domen (TLD, masalan .com yoki .net) plyus domen nomining yana bitta darajasi. Bu ko'pincha TLD+1 deb ataladi. So'rov same-site yoki yo'qligini aniqlashda URL sxemasi ham hisobga olinadi — ya'ni http://app.example.com dan https://app.example.com ga havola ko'pchilik brauzerlarda cross-site deb qaraladi.
Sayt va origin o'rtasidagi farq — ularning qamrovi: sayt bir nechta domen nomini o'z ichiga oladi, origin esa faqat bittasini. Ikki URL bir xil origin hisoblanadi, agar ular aynan bir xil sxema, domen nomi va portga ega bo'lsa. Muhimi: cross-origin so'rov baribir same-site bo'lishi mumkin, lekin aksincha emas. Quyidagi jadval bu farqni ko'rsatadi:
So'rov (dan) So'rov (ga) Same-site? Same-origin?
https://example.com https://example.com Ha Ha
https://app.example.com https://intranet.example.com Ha Yo'q (domen farqli)
https://example.com https://example.com:8080 Ha Yo'q (port farqli)
https://example.com https://example.co.uk Yo'q (eTLD farqli) Yo'q (domen farqli)
https://example.com http://example.com Yo'q (sxema farqli) Yo'q (sxema farqli)Bu muhim farq, chunki ixtiyoriy JavaScript bajarishga imkon beruvchi har qanday zaiflik xuddi shu saytga tegishli boshqa domenlardagi sayt asosidagi himoyalarni chetlab o'tish uchun suiiste'mol qilinishi mumkin.
SameSite mexanizmi joriy qilinishidan oldin brauzerlar cookie'ni chiqargan domenga har bir so'rovda yuborar edi, hatto so'rov aloqasiz uchinchi tomon sayti tomonidan ishga tushirilgan bo'lsa ham. SameSite brauzerlar va sayt egalariga qaysi cross-site so'rovlarga muayyan cookie'lar qo'shilishini cheklashga imkon beradi. Barcha yirik brauzerlar quyidagi cheklov darajalarini qo'llab-quvvatlaydi: Strict, Lax, None. Ular Set-Cookie javob sarlavhasidagi SameSite atributi orqali sozlanadi:
Set-Cookie: session=0F8tgdOhi9ynR1M9wa3ODa; SameSite=StrictSameSite=Strict bilan o'rnatilgan cookie'ni brauzerlar hech qanday cross-site so'rovda yubormaydi. Ya'ni agar so'rov nishoni brauzer manzil satridagi saytga mos kelmasa, cookie qo'shilmaydi. Bu eng xavfsiz variant, lekin cross-site funksiya kerak bo'lgan holatlarda foydalanuvchi tajribasiga salbiy ta'sir qilishi mumkin.
Lax cheklovlar cookie'ni cross-site so'rovlarda yuboradi, lekin faqat ikkala shart bajarilsa: so'rov GET metodidan foydalansa VA so'rov foydalanuvchining yuqori darajali navigatsiyasidan (masalan havolani bosish) kelib chiqsa. Ya'ni cookie cross-site POST so'rovlarga va skript/iframe kabi fon so'rovlariga qo'shilmaydi.
SameSite=None bilan o'rnatilgan cookie SameSite cheklovlarini butunlay o'chiradi — brauzer bu cookie'ni saytga barcha so'rovlarda, hatto aloqasiz uchinchi tomon saytlaridan kelganida ham yuboradi. SameSite=None bilan cookie o'rnatishda Secure atributi ham qo'shilishi shart:
Set-Cookie: trackingId=0F8tgdOhi9ynR1M9wa3ODa; SameSite=None; SecureAmalda serverlar ko'pincha berilgan endpointga GET yoki POST kelishiga ahamiyat bermaydi. Agar ular sessiya cookie'lari uchun Lax cheklovlaridan foydalansa, jabrlanuvchi brauzeridan GET so'rov chiqarib CSRF hujumini amalga oshirishingiz mumkin. So'rov yuqori darajali navigatsiyani o'z ichiga olsa, brauzer baribir sessiya cookie'sini qo'shadi:
<script>
document.location = 'https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000';
</script>Oddiy GET so'rovga ruxsat berilmasa ham, ba'zi freymvorklar so'rov metodini bekor qilish yo'llarini beradi. Masalan, Symfony formalarda _method parametrini qo'llab-quvvatlaydi:
<form action="https://vulnerable-website.com/account/transfer-payment" method="GET">
<input type="hidden" name="_method" value="POST">
<input type="hidden" name="recipient" value="hacker">
<input type="hidden" name="amount" value="1000000">
</form>Agar cookie SameSite=Strict bilan o'rnatilgan bo'lsa, brauzerlar uni hech qanday cross-site so'rovda qo'shmaydi. Xuddi shu sayt ichida ikkilamchi so'rov keltirib chiqaradigan gadjet topsangiz, bu cheklovni chetlab o'tishingiz mumkin. Bunday gadjetlardan biri — hujumchi boshqaradigan kiritma (masalan URL parametrlari) yordamida yo'naltirish manzilini dinamik quradigan client-side redirect. Brauzerlar uchun bu client-side redirectlar aslida redirect emas — natijadagi so'rov oddiy, mustaqil same-site so'rov sifatida qaraladi va saytga oid barcha cookie'larni qo'shadi.
Server tomonidagi redirect bilan ekvivalent hujum mumkin emas — bu holatda brauzerlar so'rov dastlab cross-site so'rovdan kelib chiqqanini tanib, tegishli cookie cheklovlarini qo'llaydi.
So'rov cross-origin chiqarilsa ham baribir same-site bo'lishi mumkinligini yodda tuting. Barcha mavjud hujum yuzasini, jumladan sibling (qardosh) domenlarni ham sinchiklab audit qiling. XSS kabi ixtiyoriy ikkilamchi so'rov chiqarishga imkon beruvchi zaifliklar sayt asosidagi himoyalarni butunlay buzishi mumkin. Bundan tashqari, agar nishon sayt WebSocket'larni qo'llab-quvvatlasa, bu funksiya cross-site WebSocket hijacking (CSWSH)'ga zaif bo'lishi mumkin.
Lax cheklovli cookie'lar odatda cross-site POST so'rovlarga yuborilmaydi, lekin istisnolar bor. Chrome standart Lax'ni qo'llaganda, single sign-on (SSO) mexanizmlarini buzmaslik uchun, yuqori darajali POST so'rovlarga dastlabki 120 soniya davomida bu cheklovni majburlamaydi. Natijada foydalanuvchilar cross-site hujumlarga zaif bo'lgan ikki daqiqalik oyna paydo bo'ladi. Agar saytda jabrlanuvchiga yangi sessiya cookie'si chiqarishga majbur qiladigan gadjet topsangiz (masalan OAuth login oqimi), asosiy hujumdan oldin uning cookie'sini oldindan yangilashingiz mumkin.
Popup tab'lar qo'lda o'zaro ta'sirsiz bloklanadi, shuning uchun window.open() ni onclick hodisasiga o'rab qo'yiladi:
window.onclick = () => {
window.open('https://vulnerable-website.com/login/sso');
}