Credential stuffing va akkauntni egallash: aniqlash va himoya
Chuqur4 daqInnovialabs tahririyati
Qisqacha
Credential stuffing — boshqa saytlardan sizib chiqqan login-parol juftliklarini ommaviy sinash; himoya qatlamli bo‘ladi: k-anonymity orqali buzilgan parollarni bloklash, har bir kirishni qurilma va xulq bo‘yicha baholash, ikkinchi omilni faqat xavf yuqori bo‘lganda so‘rash, botlarni filtrlash va kirish anomaliyalarini kuzatish.
Credential stuffing qanday ishlaydi
Odamlar parollarni takrorlaydi. Bitta saytning foydalanuvchilar bazasi sizib chiqqanda, hujumchilar email-parol juftliklarini olib, ularni boshqa servislarga avtomatik ravishda sinab ko‘radi: banklar, do‘konlar, yetkazib berish ilovalari, SaaS mahsulotlar. Ishlagan har bir juftlik — akkauntni egallash (account takeover, ATO): o‘g‘irlangan bonuslar, saqlangan kartalar, shaxsiy ma’lumotlar yoki firibgarlik uchun tayanch.
Nima uchun buni to‘xtatish qiyin:
- so‘rovlar rezident proksilar va minglab IP orqali keladi, shuning uchun IP bo‘yicha limitlar deyarli ishlamaydi;
- har bir akkauntga bir-ikki urinish to‘g‘ri keladi, shuning uchun akkaunt bo‘yicha bloklash ham ishlamaydi;
- botlar haqiqiy brauzerlarga taqlid qiladi, oddiy tekshiruvlarni yechadi va user agent’ni almashtiradi;
- hujumchidagi ma’lumotlar to‘g‘ri — muvaffaqiyatli kirish butunlay qonuniy ko‘rinadi.
Rate limiting baribir kerak, lekin u himoyaning o‘zi emas, faqat birinchi qatlam.
1-qatlam. Buzilgan parollarni rad eting
Agar parol ommaviy sizish bazalarida bo‘lsa, u albatta sinab ko‘riladi. Parollarni ro‘yxatdan o‘tishda, parolni o‘zgartirishda va kirishda tekshiring — NIST SP 800-63B shuni tavsiya qiladi.
Pwned Passwords servisi k-anonymity dan foydalanadi: parolni SHA-1 bilan xeshlaysiz, faqat birinchi 5 ta hex-belgini yuborasiz, shu prefiksli barcha suffikslarni olasiz va o‘zingizda solishtirasiz. Na parol, na to‘liq xesh serveringizdan chiqmaydi.
import hashlib
import requests
def is_breached(password: str) -> bool:
digest = hashlib.sha1(password.encode("utf-8")).hexdigest().upper()
prefix, suffix = digest[:5], digest[5:]
resp = requests.get(f"https://api.pwnedpasswords.com/range/{prefix}", timeout=5)
resp.raise_for_status()
return any(line.split(":")[0] == suffix for line in resp.text.splitlines())
Kirishda moslik topilsa, foydalanuvchini faqat qo‘shimcha tekshiruvdan keyin kiriting va parolni o‘zgartirishni talab qiling. Servis ishlamay qolsa nima qilishni oldindan hal qiling: odatda kirish bloklanmaydi, lekin hodisa logga yoziladi.
2-qatlam. Har bir kirish xavfini baholang
Bitta «ha/yo‘q» qoidasi o‘rniga signallarni yig‘ib, ularni xavf bahosiga jamlang:
- Qurilma: bu qurilma va brauzer akkaunt uchun tanishmi? Saqlangan qurilma tokeni yoki cookie — kuchli ijobiy signal.
- Tarmoq: data-markaz yoki hosting ASN’i, ma’lum proksi yoki Tor chiqish tuguni, foydalanuvchi hech qachon kirmagan mamlakat.
- Xulq: sahifa yuklanishi va forma yuborilishi orasidagi vaqt, yozish va kursor harakati naqshlari, sahifani yuklamasdan kirish API’siga to‘g‘ridan-to‘g‘ri POST.
- Tarix: ikki kirish orasidagi «imkonsiz ko‘chish», bitta qurilmadan bir nechta akkauntga kirish, yangi qurilmadan kirgandan so‘ng darhol parolni tiklash.
Iloji boricha signallarni serverda saqlang: mijoz yuboradigan hamma narsani soxtalashtirish mumkin.
3-qatlam. Step-up autentifikatsiya
Xavf bahosi nimani so‘rashni belgilaydi:
| Xavf | Harakat |
|---|---|
| Past | Oddiy kirish |
| O‘rta | Bir martalik kod yoki email orqali tasdiqlash |
| Yuqori | Kuchli ikkinchi omil yoki bloklash va foydalanuvchini xabardor qilish |
Passkey’lar va ilovadagi kodlar credential stuffing’dan yaxshi himoya qiladi: takror ishlatilgan parolning o‘zi endi yetarli emas. SMS-kodlar hech narsadan yaxshiroq, lekin SIM swapping’ga qarshi zaifroq. MFA’ni hammaga taklif qilib, tekshiruvni faqat xavfli kirishlarda so‘rasangiz, noqulaylik past bo‘lib qoladi.
4-qatlam. Botlarni aniqlang va sekinlashtiring
- Kirish endpoint’ini edge’dagi bot management yoki credential stuffing’ga qarshi qoidalarga ega WAF ortiga qo‘ying.
- Challenge’ni har bir kirishda emas, faqat shubhali signallarda ko‘rsating.
- Noto‘g‘ri parol va mavjud bo‘lmagan foydalanuvchi uchun bir xil xato va o‘xshash javob vaqtini qaytaring, shunda hujumchilar o‘z ro‘yxatlarini tekshira olmaydi.
- Bir vaqtning o‘zida bir nechta o‘lchov bo‘yicha cheklang: IP, subnet, ASN, qurilma, akkaunt va global.
- Barcha kirish nuqtalarini himoyalang: mobil API, parolni tiklash, eski endpoint’lar va hamkorlar kirishi ko‘pincha unutiladi.
5-qatlam. Kirish anomaliyalarini kuzating
Credential stuffing metrikalarda taniqli ko‘rinishga ega. Quyidagilarga alert sozlang:
- kirish urinishlari umumiy soni yoki muvaffaqiyatsizlar ulushining keskin oshishi;
- «foydalanuvchi topilmadi» xatolari ulushining o‘sishi — hujumchi ro‘yxatida sizda hech qachon bo‘lmagan email’lar bor;
- bitta qurilma izidan ko‘plab akkauntlarga kirish urinishlari;
- yangi qurilmalardan muvaffaqiyatli kirishlar o‘sishi va ulardan keyin email, telefon yoki to‘lov rekvizitlarining o‘zgarishi.
Hujum tasdiqlanganda: chegaralarni qattiqlashtiring, zarar ko‘rgan akkauntlar sessiyalarini yakunlang, parollarni majburan tiklang va foydalanuvchilarni yangi qurilmalardan kirish haqida xabardor qiling — ular o‘zlari ham choralar ko‘ra olsin.
Ko‘p uchraydigan xatolar
- Bitta mexanizmga, odatda CAPTCHA’ga tayanish — botlar uni yechishni autsorsga berishi mumkin.
- Bir necha muvaffaqiyatsiz urinishdan keyin akkauntni bloklash — hujumchilar shu yo‘l bilan haqiqiy foydalanuvchilarni oson bloklaydi.
- Kirish formasida «bu email ro‘yxatdan o‘tmagan» degan xabar.
- Veb-kirish himoyalangan, mobil API esa ochiq.