Xavfsizlik
Server tomonidagi himoyalar, integratsiya qoidalari, xato kodlari, token muddatlari va ishga tushirishdan oldingi tekshiruv.
Xavfsizlik modeli
Kitobchi ID OAuth 2.0 Security Best Current Practice (RFC 9700) va OAuth 2.1 talablariga mos qurilgan. Quyidagi himoyalar server tomonida majburiy va o'chirib bo'lmaydi:
| Himoya | Nimadan saqlaydi |
|---|---|
| Faqat authorization code oqimi (implicit va password grant yo'q) | Tokenlarning URL va brauzer tarixiga tushishi |
| PKCE S256 barcha ilovalar uchun majburiy | Kodni ushlab olish (code interception), kod in'eksiyasi |
| Redirect URI aniq moslik bilan; noto'g'ri bo'lsa hech qayerga yo'naltirilmaydi | Ochiq redirect, kodni begona saytga oqizish |
| state va nonce majburiy; javobda iss (RFC 9207) | CSRF, ID token qayta ishlatilishi, mix-up hujumi |
| Kod bir martalik, 5 daqiqa; qayta ishlatilsa shu koddan chiqqan barcha tokenlar bekor | O'g'irlangan kodni qayta ishlatish |
| Har qanday muvaffaqiyatsiz almashtirish urinishi kodni yoqadi | PKCE verifier'ni tanlab topish |
| Refresh token rotatsiyasi + qayta ishlatishni aniqlash (butun oila bekor) | O'g'irlangan refresh token |
| Access token 10 daqiqa, typ: at+jwt; ID tokenni Bearer sifatida qabul qilinmaydi | Token almashtirish (token confusion) |
| Kod, refresh token va client secret bazada faqat hash (SHA-256 / bcrypt) | Baza sizib chiqqanda tokenlardan foydalanish |
| RS256 + kid, kalit rotatsiyasi bilan; alg: none va HS256 hech qachon | Imzoni soxtalashtirish, algoritm almashtirish |
| Pairwise sub hamkor ilovalar uchun | Ilovalararo foydalanuvchini kuzatish |
| SMS kod: HMAC bilan saqlanadi, 5 urinish, 60 s qayta yuborish, kuniga 10 ta; SMS'da ilova nomi; master-kod yo'q | Kodni tanlab topish, SMS-bombing, fishing |
| Kod avval foydalanuvchining faol Kitobchi ilovasiga (rasmiy chat + push), keyin SMS; kod chat bazasi va websocket'ga yozilmaydi, faqat chat egasiga shifrlangan holda beriladi | Xodimlar yoki do'kon paneli orqali kodning sizib chiqishi, SIM-almashtirish |
| Kirish sahifalari: frame-ancestors 'none', CSRF, no-store, no-referrer, sessiya ID login'dan keyin yangilanadi | Clickjacking, CSRF, sessiya fiksatsiyasi |
| Bloklangan yoki o'chirilgan akkaunt — refresh va userinfo darhol ishlamaydi | Bloklangan foydalanuvchining eski tokenlari |
| IP bo'yicha so'rov limitlari (authorize 60/daq, SMS 5/daq, token 60/daq) | Brute-force va DoS |
Integratsiya qiluvchi uchun qoidalar
- client_secret faqat serverda — muhit o'zgaruvchisi yoki secret manager'da. Git, frontend, mobil ilova, log va xato xabarlariga tushmasin. Sizib chiqsa — darhol bizga yozing, secret almashtiriladi.
- Tokenlarni brauzerga bermang — SPA bo'lsangiz ham «backend-for-frontend» (BFF) yondashuvi: tokenlar serverda, brauzerda faqat httpOnly + Secure + SameSite=Lax sessiya cookie'si.
- Refresh tokenni shifrlab saqlang (mobil: Keychain / Android Keystore orqali secure storage). Hech qachon localStorage'da emas.
- Tokenlarni log qilmang — so'rov loglarida Authorization header, code, refresh_token maskalansin.
- Akkauntni faqat sub bo'yicha bog'lang. Mavjud akkauntni telefon raqami bo'yicha avtomatik birlashtirmang — foydalanuvchidan mavjud akkauntga kirib tasdiqlashni so'rang.
- JWKS'ni keshlang (≤ 15 daq), noma'lum kid kelsa bir marta qayta yuklang — kalit rotatsiyasi shunday ishlaydi.
- Mobil: WebView yo'q — faqat tizim brauzeri (Custom Tabs / ASWebAuthenticationSession) va imkon qadar App Links / Universal Links.
- Faqat kerakli scope — kam ma'lumot so'ragan ilova ko'proq ishonch qozonadi. Telefon raqam kerak bo'lmasa phone so'ramang.
- Shaxsga doir ma'lumotlar — olingan ma'lumotlarni O'zbekiston Respublikasining «Shaxsga doir ma'lumotlar to'g'risida»gi qonuniga muvofiq qayta ishlang, o'z maxfiylik siyosatingizda Kitobchi ID'ni ko'rsating va foydalanuvchi so'roviga ko'ra o'chiring.
Xato kodlari
/authorize (redirect_uri ga qaytadi)
| error | Sabab | Nima qilish kerak |
|---|---|---|
| invalid_request | state/nonce/PKCE yo'q yoki noto'g'ri, parametr takrorlangan | So'rovni tuzating |
| unsupported_response_type | response_type ≠ code | Faqat code flow |
| invalid_scope | openid yo'q, noma'lum yoki ilovaga ruxsat berilmagan scope | Scope ro'yxatini tekshiring |
| access_denied | Foydalanuvchi «Rad etish»ni bosdi | Odatiy holat — kirish sahifasiga qaytaring |
| login_required, consent_required | prompt=none, lekin kirish yoki rozilik kerak | prompt'siz qayta yo'naltiring |
| request_not_supported | request/request_uri parametrlari | Oddiy query parametrlardan foydalaning |
Agar client_id yoki redirect_uri noto'g'ri bo'lsa, xavfsizlik uchun foydalanuvchi ilovangizga qaytarilmaydi — Kitobchi ID xato sahifasini ko'radi.
/token, /revoke (JSON)
| HTTP | error | Sabab |
|---|---|---|
| 400 | invalid_request | Parametr yo'q, Content-Type form emas, ikki xil client autentifikatsiyasi |
| 401 | invalid_client | client_id/secret noto'g'ri, ilova o'chirilgan, public ilova secret yubordi |
| 400 | invalid_grant | Kod/refresh token yaroqsiz, muddati o'tgan, ishlatilgan, PKCE yoki redirect_uri mos emas, akkaunt bloklangan |
| 400 | invalid_scope | Refresh'da kengroq scope so'raldi |
| 400 | unsupported_grant_type | Faqat authorization_code va refresh_token |
| 429 | — | So'rov limiti; Retry-After ga amal qiling |
invalid_grant refresh paytida kelsa — lokal sessiyani yoping va foydalanuvchini qayta kirishga yuboring. Qayta-qayta urinmang.
Muddatlar
| Element | Muddat |
|---|---|
| Authorization code | 5 daqiqa, bir martalik |
| Access token | 10 daqiqa |
| ID token | 1 soat (faqat kirish paytida tekshiriladi) |
| Refresh token | 30 kun sirpanuvchi, maksimal 90 kun |
| Kitobchi ID brauzer sessiyasi | 30 kungacha (max_age / prompt=login bilan qisqartirish mumkin) |
| SMS kod | 5 daqiqa, 5 urinish |
Ishga tushirishdan oldin
- state, nonce va code_verifier har urinish uchun yangi va tasodifiy
- Callback’da state va iss tekshiriladi, state bir martalik
- ID token: imzo (RS256), iss, aud, exp, nonce tekshiriladi
- Foydalanuvchi bazada (issuer, sub) bo‘yicha saqlanadi
- client_secret faqat serverda; mobil/SPA — public client
- Refresh token shifrlangan, rotatsiya atomik, invalid_grant’da qayta login
- Chiqishda /revoke chaqiriladi
- Kirish tugmasi brend qoidalariga mos
Zaiflik topdingizmi? Iltimos, ommaga e'lon qilishdan oldin toordaliev@gmail.com ga yoki Telegram: @kitobchi_support ga yozing. Tasdiqlangan topilmalar uchun minnatdorchilik bildiramiz.