Asosiy kontentga o‘tish

Maqolalar 8 daqiqa 41 ko‘rish

OWASP Top 10: backend dasturchi uchun tirik qo‘llanma

Web-xavfsizlikdagi eng nufuzli ro‘yxatning 2025-yilgi versiyasini quruq ta'riflar bilan emas, har biri qanday ko‘rinishda uchrashi va nima bilan yopilishi tomonidan ko‘rib chiqamiz. 2021-dan keyin tartib o‘zgargan, bitta band umuman yangi. Eng ko‘p uchraydigan zaiflikni esa kod bilan ochib beraman.

security backend

Mundarija

OWASP Top 10 — web-xavfsizlikdagi eng nufuzli ro‘yxat. Uni butun dunyo bo‘ylab xavfsizlik mutaxassislari tuzadi va eng ko‘p uchraydigan, eng zararli zaiflik toifalarini bir joyga jamlaydi. Backend yozadigan har bir odam bu o‘nta narsani bilishi kerak, chunki ular kitobdagi nazariya emas — aynan shu xatolardan haqiqiy loyihalar buziladi.

Ro‘yxat bir necha yilda bir yangilanadi va quyida 2025-yilgi, ya'ni hozirgi kunda amaldagi versiyasi keltirilgan. Buni alohida aytishimning sababi bor: ko‘pchilik hali 2021-yilgi ro‘yxatni yoddan biladi, 2025-da esa tartib sezilarli o‘zgargan. Eng kattasi — kutubxona zaifliklari endi kengaytirilib, supply chain deb ataladi va uchinchi o‘ringa ko‘tarilgan; sozlama xatolari beshinchidan ikkinchiga chiqqan; SSRF esa alohida band bo‘lmay qoldi va birinchi toifaga qo‘shib yuborildi. O‘rniga butunlay yangi bir toifa paydo bo‘ldi — uni oxirida ko‘ramiz.

Men bu ro‘yxatni quruq ta'riflar bilan emas, har birini "amalda qanday ko‘rinadi va nima bilan yopiladi" tomonidan ko‘rib chiqaman. Birinchisini esa, eng ko‘p uchraydiganini, kod bilan ochib beraman.

1. Broken Access Control — eng ko‘p uchraydigani#

Ro‘yxat boshida turgani bejiz emas. Bu zaiflikning mohiyati oddiy: foydalanuvchi o‘ziga tegishli bo‘lmagan ma'lumotga kira oladi. Buni tasavvur qilish uchun kod ham shart emas, faqat bitta manzarani ko‘z oldingizga keltiring. Sizda buyurtmalarni ko‘rsatadigan endpoint bor:

Python
# ZAIF: buyurtmani ID bo'yicha topadi, lekin EGASINI tekshirmaydi
def get_order(request, order_id):
    order = Order.objects.get(id=order_id)
    return JsonResponse(order.as_dict())

Foydalanuvchi /orders/1041/ ni ochadi va o‘z buyurtmasini ko‘radi. Tabiiy. Endi u manzil satridagi raqamni 1042 ga o‘zgartiradi va... boshqa odamning buyurtmasi ochiladi: ismi, manzili, telefoni. Hech qanday hujum tool'i kerak emas, faqat raqamni oshirib borish kifoya. Bunday zaiflikni topadigan avtomatik skriptlar esa allaqachon internetda yuradi.

To‘g‘ri variantda so‘rov har doim joriy foydalanuvchi bilan cheklanadi:

Python
# TO'G'RI: faqat so'rov yuborgan odamning o'z buyurtmasi
def get_order(request, order_id):
    order = get_object_or_404(Order, id=order_id, owner=request.user)
    return JsonResponse(order.as_dict())

Bu yerda get_object_or_404 ni objects.get o‘rniga ishlatganim bejiz emas. objects.get topolmasa Order.DoesNotExist ko‘taradi va u ushlanmasa foydalanuvchi 500 oladi — ya'ni siz IDOR'ni yopib, o‘rniga server xatosi ochib qo‘yasiz. Ustiga 500 bilan 404 ning farqi hujumchiga axborot beradi: qaysi ID mavjudligini shundan bilib oladi. get_object_or_404 esa ikkala holatda ham bir xil, quruq 404 qaytaradi — "bunday buyurtma sizda yo‘q" degani, "bor, lekin sizniki emas" degani emas.

Asosiy qoida shu: ruxsatni har doim server tomonida tekshiring. Frontend tugmani yashirgani hech narsani anglatmaydi — so‘rovni to‘g‘ridan-to‘g‘ri yuborish mumkin.

Yana bir narsa aynan shu bandga tegishli: SSRF. Ilgari u alohida, o‘ninchi o‘rinda turardi, 2025-yilgi ro‘yxatda esa shu yerga ko‘chdi — va mantiqan to‘g‘ri, chunki bu ham chegarani buzib o‘tish. Mohiyati: server hujumchi ko‘rsatgan manzilga so‘rov yuborishga aldanadi. Foydalanuvchi bergan URL'dan rasm yuklab oladigan funksiyangiz bo‘lsa, hujumchi u yerga tashqi rasm o‘rniga ichki tarmoq manzilini beradi va server tashqariga yopiq xizmatga o‘z nomidan kiradi. Davosi — foydalanuvchi bergan URL'larni tekshirish va ichki manzillarga so‘rovni taqiqlash.

2. Security Misconfiguration#

Standart parollar, ochiq qolgan debug rejimi, keraksiz ochiq portlar. Bu eng "achinarli" toifa, chunki bu yerda kod to‘g‘ri, faqat sozlama noto‘g‘ri — va aynan shuning uchun u 2025-yilgi ro‘yxatda beshinchidan ikkinchi o‘ringa ko‘tarildi. Django'da eng klassik holat — production'da DEBUG=True qolib ketishi: u xato sahifalarida butun sozlamalarni, hatto maxfiy kalitlarni ham ko‘rsatib qo‘yadi.

3. Software Supply Chain Failures#

Ilgari bu band "eskirgan kutubxonalar" deb atalardi. 2025-da uning doirasi kengaydi va nomi ham o‘zgardi: gap endi faqat sizning pyproject.toml dagi versiyalar haqida emas, balki kod sizning serveringizgacha yetib keladigan butun yo‘l haqida — paketlar, ular olinadigan registry, CI zanjiringiz, hatto dasturchining noutbuki. Va bu bejiz emas: oxirgi yillardagi eng katta buzilishlar aynan shu yo‘lda sodir bo‘ldi — yetkazib beruvchining yangilanishi zaharlangan SolarWinds hodisasi, npm ekotizimi bo‘ylab o‘zini o‘zi tarqatgan qurt, Log4Shell.

Eng oddiy birinchi qadam — o‘zingizdagi paketlarni ma'lum zaifliklar bazasi bilan solishtirish. pip-audit shuni qiladi, uni o‘rnatib ham o‘tirmasdan chaqirsa bo‘ladi:

Terminal
uv run --with pip-audit pip-audit

Sinab ko‘rish uchun men ataylab eski Django o‘rnatilgan loyihada ishga tushirdim:

Natija
Found 93 known vulnerabilities in 1 package
Name   Version ID              Fix Versions
------ ------- --------------- ---------------------------------------
django 4.2     PYSEC-2023-61   3.2.19,4.1.9,4.2.1
django 4.2     PYSEC-2023-100  3.2.20,4.1.10,4.2.3
django 4.2     PYSEC-2023-222  3.2.23,4.1.13,4.2.7
...

Bitta paket, to‘qson uchta ma'lum zaiflik — va ularning hammasi uchun tuzatilgan versiya allaqachon chiqqan. Buni CI zanjiriga qo‘shib qo‘ysangiz, zaif kutubxona kirib qolganda darhol xabar topasiz.

Nega pip install pip-audit emas

uv bilan ishlaganda pip-audit ni oddiy o‘rnatsangiz, u ko‘pincha noto‘g‘ri muhitni tekshiradi va "hech qanday zaiflik yo‘q" deb tinchlantirib qo‘yadi — men buni ham sinab ko‘rdim. uv run --with esa uni loyihangizning o‘z muhitida ishga tushiradi, ya'ni aynan siz ishlatayotgan paketlarni tekshiradi.

4. Cryptographic Failures#

Maxfiy ma'lumot ochiq yoki zaif himoyada saqlanadi. Amalda bu parollarni oddiy hash bilan saqlash, ma'lumotni HTTPS'siz uzatish yoki maxfiy kalitlarni kod ichida qoldirish ko‘rinishida bo‘ladi. Yechim ham shu joylardan o‘tadi: parollar uchun Argon2, transport uchun TLS, kalitlar uchun esa muhit o‘zgaruvchilari.

5. Injection#

Foydalanuvchi kiritmasi kodga aylanib qoladigan har qanday holat. Eng mashhuri — SQL injection, buni alohida maqolada o‘z qo‘limiz bilan sinab ko‘rgan edik. Bir xil printsip buyruq satriga ham (command injection), shablonlarga ham tegishli: kiritmani hech qachon buyruqning ichiga yopishtirmang, parametr sifatida uzating.

6. Insecure Design#

Bu boshqalaridan farq qiladi — bu aniq bir kod xatosi emas, balki xavfsizlik haqida umuman o‘ylanmagani. Masalan, parolni tiklash tizimida SMS kodni tekshirish soni cheklanmagan bo‘lsa, bu bitta qatorlik xato emas, dizayndagi kamchilik. Davosi ham dizayn bosqichida: yangi funksiyani rejalashtirganda "buni kim, qanday suiiste'mol qilishi mumkin?" degan savolni berish.

7. Authentication Failures#

Zaif parol talablari, brute-force himoyasining yo‘qligi, sessiyalarni noto‘g‘ri boshqarish. Bu yerda yordamchilar tanish: rate limiting parol terishni to‘xtatadi, kuchli hash parolni himoya qiladi, ikki bosqichli tekshiruv esa qatlam qo‘shadi.

8. Software or Data Integrity Failures#

Ishonchsiz manbadan kelgan ma'lumotga yoki yangilanishga ko‘r-ko‘rona ishonish. Amaliy misol: tashqi xizmatdan kelgan "webhook" so‘roviga uning signature'ini tekshirmasdan ishonish. Har kim o‘sha manzilga soxta so‘rov yuborib, tizimingizni aldashi mumkin bo‘lib qoladi.

9. Security Logging and Alerting Failures#

Hujum bo‘lganda uni aniqlash uchun izlar kerak. Agar login urinishlari, ruxsat rad etilishi kabi muhim hodisalar loglanmasa, hujumni ko‘p vaqt o‘tgach, allaqachon kech bo‘lganda bilib qolasiz. Nom 2025-da biroz o‘zgargani ham shuni ta'kidlaydi: endi u faqat "logging" emas, "logging and alerting" — ya'ni log yozilishining o‘zi yetarli emas, kimdir o‘sha logga qarab xabar olishi kerak. Teskari xato ham bor: loglarga parol yoki token yozib qo‘yish — bu o‘zi yangi zaiflik.

10. Mishandling of Exceptional Conditions — yangi band#

Bu 2025-yilgi ro‘yxatning yangiligi va menimcha eng qiziq bandi, chunki u ko‘pchilik "xavfsizlik emas, shunchaki sifat masalasi" deb hisoblaydigan narsani xavfsizlik zaifligi deb ataydi. Mohiyati: dastur kutilmagan holatga tushganda — xato, chekka qiymat, tugab qolgan resurs — uni oldini ololmaydi, payqamaydi yoki noto‘g‘ri javob beradi.

Uch ko‘rinishi eng ko‘p uchraydi. Birinchisi — xato xabarining o‘zi ma'lumot sizdirishi: to‘liq traceback, SQL so‘rovi yoki fayl yo‘li foydalanuvchiga chiqib ketadi. Ikkinchisi — fail open: tekshiruv xato bersa, kod uni "o‘tkazib yuborish" deb talqin qiladi. Bu ayniqsa yomon, chunki except: pass yozilgan ruxsat tekshiruvi — aslida ruxsat tekshiruvining yo‘qligi. Uchinchisi — yarim bajarilgan amaliyot: pul yechildi, buyurtma yaratilmadi, hech kim orqaga qaytarmadi.

Amaliy javobi ham shu uchtasiga qarab tuziladi: xatoni u chiqqan joyda, ma'noli tarzda ushlang; shubha bo‘lsa fail closed tanlang, ya'ni ruxsat bermang; pul va buyurtma kabi narsalarni tranzaksiya ichida bajarib, xatoda butunlay orqaga qaytaring; foydalanuvchiga esa qisqa xabar, log'ga to‘liq tafsilot yozing.

Bularni qanday yodda tutish kerak#

Ro‘yxatni yodlab olishning hojati yo‘q, undan foydalanishning to‘g‘ri usuli boshqacha. Har yangi funksiya yozayotganda bitta savolni bering: "buni kim, qanday buzishi mumkin?" O‘sha savol o‘z-o‘zidan sizni yuqoridagi o‘nta toifadan biriga olib boradi. Xavfsizlik bir marta bajariladigan bosqich emas, u kod yozishning doimiy hamrohi. To‘liq va yangilanib turadigan ro‘yxat esa owasp.org da yashaydi.

8 daqiqa 41 marta o‘qildi