# SQL injection va undan himoya

> SQL injection nima va u qanday xavf tug'diradi? Foydalanuvchi kiritmasini so'rovga qo'shishning xavfi va parametrli so'rovlar bilan himoyalanish usuli.

Manba: https://learncode.uz/sql/sql-injection/
Sana: 2026-06-21

Baza bilan ishlaydigan dasturda so'rovlar ko'pincha foydalanuvchi
kiritmasidan quriladi — masalan ism bo'yicha qidiruv. Agar bu noto'g'ri
qilinsa, buzg'unchi so'rovni o'zgartirib, butun bazani buzishi mumkin. Bu
hujum **SQL injection** deyiladi. Bu darsda uning mohiyati va himoyasini
ko'ramiz.

## Muammo: kiritmani to'g'ridan qo'shish

Aytaylik, dastur ism bo'yicha qidiradi va so'rovni **satrlarni ulab** quradi:

```python
kiritma = input("Ism: ")
so'rov = "SELECT * FROM mijozlar WHERE ism = '" + kiritma + "'"
```

Oddiy ism (`Aziz`) uchun ishlaydi. Lekin buzg'unchi shunday yozsa:

```
'; DROP TABLE mijozlar; --
```

So'rov quyidagiga aylanadi va `mijozlar` jadvali **o'chib ketadi**:

```sql
SELECT * FROM mijozlar WHERE ism = ''; DROP TABLE mijozlar; --'
```

Buzg'unchi `OR '1'='1'` yozsa, shart **har doim rost** bo'ladi va so'rov
butun jadvalni qaytaradi:

```sql
SELECT * FROM mijozlar WHERE ism = '' OR '1'='1';
```

`ism = ''` hech kimga to'g'ri kelmaydi, lekin `'1'='1'` doim rost. `OR`
tufayli har qator shartdan o'tadi — natijada to'rt mijozning hammasi
ochiladi:

| id | ism | shahar | yosh |
|---|---|---|---|
| 1 | Aziz | Toshkent | 28 |
| 2 | Dilnoza | Samarqand | 34 |
| 3 | Bobur | Toshkent | 22 |
| 4 | Malika | Buxoro | NULL |

Kiritma kod sifatida bajarildi — mana SQL injection.

> **Nega bu yerda runner yo'q**
>
> Hujum so'rovi ataylab **ishga tushiriladigan holatda berilmadi**. Zararli
> namunani nusxalab bajarish odatiga aylantirmaslik uchun uni faqat matn
> sifatida o'qiysiz. Quyidagi xavfsiz so'rov esa ishlaydi — uni asl hujum
> bilan solishtiring:

```sql
SELECT * FROM mijozlar WHERE ism = 'Aziz';
```

> **Atama**
>
> **SQL injection** — foydalanuvchi kiritmasi orqali so'rovga begona SQL
> "qistirish" hujumi. Sabab: kiritma **ma'lumot** o'rniga **kod** sifatida
> talqin qilinadi. Bu — veb-ilovalardagi eng keng tarqalgan xavfsizlik
> kamchiliklaridan biri.

## Yechim: parametrli so'rov

Himoya — kiritmani so'rovga **ulab yozmaslik**, balki uni alohida **parametr**
sifatida uzatish. Kod ichida `?` belgisi qo'yiladi, qiymat esa alohida
beriladi:

```python
kiritma = input("Ism: ")
cursor.execute(
    "SELECT * FROM mijozlar WHERE ism = ?",
    (kiritma,)
)
```

Endi baza `kiritma` ni **faqat ma'lumot** deb qabul qiladi — ichidagi SQL hech
qachon bajarilmaydi. `'; DROP TABLE ...` yozilsa ham, u shunchaki qidiriladigan
matn bo'lib qoladi, kod emas.

> **Boshlovchilar tez-tez yanglishadigan joy**
>
> Foydalanuvchi kiritmasini **hech qachon** to'g'ridan-to'g'ri so'rovga ulamang
> — hatto "ishonchli" joyda ham. Doim parametrli so'rov (`?`) ishlating. Bu
> qoida oddiy, lekin uni buzish eng katta xavfsizlik xatolaridan biriga olib
> keladi.

## Amaliy mashq

Hujumni tushunib, himoyani o'rganing:

1. Yuqoridagi hujum so'rovini (`SELECT * FROM mijozlar WHERE ism = ''
   OR '1'='1';`) matn blokidan qo'lda ko'chirib, sahifadagi runner'ga
   qo'ying va ishga tushiring;
2. natijaga qarang — nechta qator qaytdi va nega?
3. oddiy `WHERE ism = 'Aziz'` bilan solishtiring — qatorlar soni qancha
   farq qildi?
4. `OR '1'='1'` qismi shartni qanday o'zgartirganini tushuntiring;
5. qog'ozda yozing: bu so'rov foydalanuvchi kiritmasidan qurilganda
   dasturchi qanday xato qilgan?
6. o'sha so'rovni `?` parametrli ko'rinishda qayta yozing va kiritma
   endi nega kod emas, ma'lumot bo'lib qolishini tushuntiring.

Himoya yo'li — parametrlangan so'rov. Nega oddiy qo'shtirnoq yetarli emas?

## Qisqacha xulosa

- **SQL injection** — kiritma orqali so'rovga begona SQL qo'shish hujumi.
- Sabab: kiritma **kod** sifatida talqin qilinishi.
- Xavf: ma'lumotni o'g'irlash, o'zgartirish yoki butun jadvalni o'chirish.
- Himoya: **parametrli so'rov** (`?` bilan) — kiritma faqat ma'lumot bo'ladi.
- Kiritmani hech qachon so'rovga to'g'ridan-to'g'ri ulamang.

Keyingi darsda [ER-model va baza dizayni](https://learncode.uz/sql/er-model) — bazani qurishdan
oldin uni to'g'ri rejalashtirishni ko'ramiz.
