Va eng kam yordam siz ishlab chiqqan funksiyadan bo'ladi. PHP: \"Quotes\". MySQL so'rovlarini yozish, slashlar, qo'shtirnoqlardan qochish Kodda qidirish

tirnoq qatori (11)

Men so'rovlarni yozishning eng yaxshi usulini topishga harakat qilaman. Men ham izchil bo'lish muhimligini tushunaman. Hozirgacha men tasodifiy ravishda bitta tirnoq, qo'sh tirnoq va orqa belgilarni hech qanday o'ylamasdan ishlatganman.

$query = "Jadvalga INSERT INTO (id, col1, col2) VALUES (NULL, val1, val2)";

Shuningdek, yuqoridagi misolda "jadval", "col[n]" va "val[n]" o'zgaruvchilar bo'lishi mumkinligini ko'rib chiqing.

Buning standarti qanday? Nima bilan bandsan?

Men shunga o'xshash savollarga javoblarni taxminan 20 daqiqa davomida o'qiyapman, ammo bu savolga aniq javob yo'qdek.

Javoblar

Endi siz MySQL so'rovida to'g'ridan-to'g'ri post o'zgaruvchisidan foydalanyapsiz deylik, keyin uni quyidagicha ishlating:

$query = "Jadvalga INSERT INTO (`id`, `name`, `email`) VALUES (" ".$_POST["id"]." ", " ".$_POST["nom"]." ", " ".$_POST["elektron pochta"].." ")";

Bu MySQL-da PHP o'zgaruvchilardan foydalanishning eng yaxshi amaliyotidir.

Asosan Mysql da bu turdagi identifikatorlar ` , " , " va () so'rovlarida qo'llaniladi.

    " yoki " qatorni "26/01/2014 00:00:00" yoki "26/01/2014 00:00:00" qiymati sifatida kiritish uchun foydalaning. Bu identifikator faqat "01/26/2014 00:00:00" qator funksiyasi uchun ishlatiladi, masalan, now() yoki sum ,max .

    ` jadval yoki jadvalni kiritish uchun foydalaning, masalan, id = "2" bo'lgan jadval_nomidan ustun_nomini tanlang.

    () faqat soʻrov qismlarini oʻrab olish uchun ishlatiladi, masalan, jadval_nomi (id = "2" va jins = "erkak") yoki name = "rakesh" dan ustun_nomini tanlang.

Barcha (yaxshi tushuntirilgan) javoblardan tashqari, quyida hech kim aytilmagan va men bu savol-javobga tez-tez kelaman.

Qisqasini etkanda; MySQL siz matematika bilan shug'ullanishni xohlaysiz deb o'ylaydi o'zingizning jadvalingiz/ustuningizda va "elektron pochta" kabi defislarni elektron pochta sifatida izohlang.

Mas'uliyatni rad etish. Shunday qilib, men buni ma'lumotlar bazalari bilan ishlashga mutlaqo yangi bo'lgan va yuqorida tavsiflangan texnik shartlarni tushunmasligi mumkin bo'lganlar uchun "Ma'lumot uchun" javob sifatida qo'shishni o'yladim.

(Savolingizning SQL xususiyatiga oid yuqorida yaxshi javoblar mavjud, ammo agar siz PHPda yangi bo'lsangiz, bu ham tegishli bo'lishi mumkin.)

Shuni ta'kidlash kerakki, PHP bitta va qo'sh tirnoqlarga boshqacha munosabatda bo'ladi...

Bitta tirnoqli satrlar "harf" va juda ko'p WYSIWYG satrlari. Ikki tirnoqli satrlar mumkin bo'lgan o'zgaruvchilarni almashtirish uchun PHP tomonidan talqin qilinadi (PHP-dagi orqaga havolalar aniq satrlar emas, ular qobiqdagi buyruqni bajaradi va natijani qaytaradi).

$foo = "bar"; echo "$foo bor"; // $foo aks-sadosi bor "$foo bor"; // bor echo `ls -l`; // ... katalog ro'yxati

Agar cols jadvallari va qiymatlari o'zgaruvchi bo'lsa, unda ikkita yo'l bor:

Ikki tirnoqli "" bilan to'liq so'rov:

$query = "INSERT INTO $table_name (id, $col1, $col2) VALUES (NULL, "$val1", "$val2")";

$query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.") VALUES (NULL, "".$val1.", "".$val2."") ";

Bitta tirnoqli "" :

$query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.") VALUES (NULL, ".$val1.", ".$val2.")";

Ustun/qiymat nomi MySQL-da zahiradagi kalit so'zga o'xshash bo'lsa, "backtick" dan foydalaning.

Eslatma. Jadval nomi bilan ustun nomini belgilasangiz, quyidagi kabi teskari belgilardan foydalaning:

`jadval_nomi` . `ustun_nomi`<- Примечание: исключить. из задних клещей.

Jadval va ustunlar identifikatorlari uchun orqa belgilar ishlatilishi kerak, lekin faqat identifikator MySQL tomonidan ajratilgan kalit so'z bo'lsa yoki identifikator cheklangan to'plamdan tashqari bo'sh joy yoki belgilarni o'z ichiga olgan bo'lsa kerak bo'ladi (pastga qarang). Iqtibos muammosini oldini olish uchun iloji bo'lsa, ustun yoki jadval identifikatorlari sifatida zaxiralangan kalit so'zlardan foydalanishdan qochish tavsiya etiladi.

VALUES() roʻyxatidagi kabi satr qiymatlari uchun bitta tirnoq qoʻllanilishi kerak. Ikkita tirnoq MySQL tomonidan qator qiymatlari uchun ham qo'llab-quvvatlanadi, lekin bitta tirnoq boshqa RDBMSlar tomonidan kengroq qabul qilinadi, shuning uchun qo'sh tirnoq o'rniga bitta tirnoqdan foydalanish yaxshidir.

MySQL shuningdek, DATE va DATETIME so'zma-so'z qiymatlari "2001-01-01 00:00:00" kabi qatorlar sifatida bitta tirnoqli bo'lishini kutadi. Qo'shimcha ma'lumot olish uchun Sana va vaqt adabiyoti hujjatlariga qarang, ayniqsa defisni sana satrlarida segment ajratuvchi sifatida ishlatishning muqobil variantlari.

Shunday qilib, sizning misolingizdan foydalanib, men PHP qatorini ikki marta uzataman va "val1", "val2" qiymatlari uchun bitta tirnoq ishlataman. NULL MySQL kalit so'zi va qiymat bo'lmagan va shuning uchun ishlatilmaydi.

Ushbu jadval yoki ustun identifikatorlarining hech biri ajratilgan so'zlar yoki iqtibos keltirishni talab qiladigan belgilardan foydalanmaydi, lekin men ularni baribir orqaga qarab keltirdim (bu haqda keyinroq...).

RDBMS bilan bog'liq funktsiyalar (masalan, MySQL-dagi NOW() kabi) iqtibos keltirilmasligi kerak, garchi ularning argumentlari bir xil qoidalarga yoki yuqorida aytib o'tilgan iqtibos qoidalariga bo'ysunadi.

Backtick(`) jadval va ustun ┬──── ┬──┬───────┐ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ry = ↓ ↓ ↓ " INSERT INTO `jadval` (`id`, `col1`, `col2`, `sana`, `yangilangan`) VALUES (NULL, "val1", "val2", "2001-01-01", NOW())"; Qo'shtirnoqsiz kalit so'z ─────┴┴┴┘ │ │ │ │ │ │ │││││ Bir tirnoqli (") satrlar ──────────────── ─ ───┴── ┴────┘ │ │ │││││ Bitta tirnoqli (") Sana ───────────────────────────────── ─ ───┴── Qo'shtirnoqsiz funksiya ───────────────────────── ───── ──────────────────── ──┴┴┴┴┘

O'zgaruvchan interpolyatsiya

O'zgaruvchilar uchun kotirovka naqshlari o'zgarmaydi, garchi siz o'zgaruvchilarni to'g'ridan-to'g'ri satrda interpolyatsiya qilmoqchi bo'lsangiz, u PHPda qo'sh tirnoq bilan belgilanishi kerak. SQL-da foydalanish uchun o'zgaruvchilardan to'g'ri qochishingizga ishonch hosil qiling. (SQL in'ektsiyasidan himoya qilish o'rniga tayyorlangan bayonotlarni qo'llab-quvvatlaydigan APIdan foydalanish tavsiya etiladi.)

// Ba'zi o'zgaruvchilarni almashtirish bilan bir xil narsa // Bu erda o'zgaruvchi jadval nomi $table teskari tirnoq bilan, VALUES ro'yxatidagi // o'zgaruvchilar esa bitta tirnoqli $query = "INSERT INTO" `$stol`(`id`, `col1`, `col2`, `sana`) VALUES (NULL, "$val1", "$val2", "$date")";

Tayyorlangan bayonotlar

Tayyorlangan bayonotlar bilan ishlaganda, bayonot to'ldiruvchilarini kiritish kerakligini aniqlash uchun hujjatlarga murojaat qiling. PHP, PDO va MySQLi-da mavjud bo'lgan eng mashhur APIlar o'z ichiga oladi ruxsatsiz boshqa tillardagi ko'pgina tayyorlangan yo'riqnomalar API kabi to'ldiruvchilar:

// Nomlangan parametrlar bilan PDO misoli, tirnoqsiz $query = "INSERT INTO `jadval` (`id`, `col1`, `col2`, `date`) VALUES (:id, :col1, :col2, :date)" ; // MySQLi misoli bilan? parametrlar, tirnoqsiz $query = "Jadvalga INSERT INTO '('id', 'col1', 'col2', 'sana') VALUES (?, ?, ?, ?)";

Identifikatorlarda orqaga havolani qaytaruvchi belgilar:

Masalan:

Jadval nomlari va maydon nomlari uchun ham xuddi shunday qilish mumkin. Bu juda yaxshi odat agar siz ma'lumotlar bazasi identifikatorini orqa oynalar bilan bog'lasangiz.

Teskari xulosalar haqida ko'proq bilish uchun ushbu javobni tekshiring.

Endi qo'sh tirnoq va bitta tirnoq haqida (Maykl buni allaqachon aytib o'tgan).

Ammo qiymatni aniqlash uchun siz bitta yoki ikkita tirnoqdan foydalanishingiz kerak. Keling, yana bir misolni ko'rib chiqaylik.

INSERT INTO `tablename` (`id, `title`) VALUES (NULL, title1);

Bu yerda men ataylab sarlavha1 ni qo'shtirnoq ichiga o'rashni unutibman. Server endi sarlavha1 ni ustun nomi (ya'ni identifikator) sifatida qabul qiladi. Shunday qilib, bu qiymat ekanligini ko'rsatish uchun siz ikkita yoki bitta tirnoqdan foydalanishingiz kerak.

INSERT INTO `tablename` (`id, `title`) VALUES (NULL, "title1");

Endi PHP bilan birgalikda qo'sh tirnoq va bitta tirnoq so'rov yozishni ancha osonlashtiradi. Keling, sizning savolingizdagi so'rovning o'zgartirilgan versiyasini ko'rib chiqaylik.

$query = "INSERT INTO `jadval` (`id`, `col1`, `col2`) VALUES (NULL, "$val1", "$val2"");

Endi, PHP da qoʻsh qoʻshtirnoq yordamida siz $val1 va $val2 oʻzgaruvchilari oʻz qiymatlaridan foydalanishga majbur qilasiz va shu bilan toʻgʻri soʻrov yaratasiz. kabi

$val1 = "mening qiymatim 1"; $val2 = "mening qiymatim 2"; $query = "INSERT INTO `jadval` (`id`, `col1`, `col2`) VALUES (NULL, "$val1", "$val2"");

INSERT INTO `jadval` (`id`, `col1`, `col2`) VALUES (NULL, "mening qiymatim 1", "mening qiymatim 2")

Bu erda juda ko'p foydali javoblar bor edi, odatda ikkita nuqta bilan yakunlanadi.

  1. BACKTICKS (`) identifikator nomlari atrofida ishlatiladi.
  2. Yagona tirnoq (") qiymatlar atrofida ishlatiladi.

Va @MichaelBerkowski aytganidek

Jadval va ustunlar identifikatorlari uchun orqa belgilar ishlatilishi kerak, lekin faqat identifikator MySQL tomonidan ajratilgan kalit so'z bo'lsa yoki identifikator cheklangan to'plamdan tashqari bo'sh joy yoki belgilarni o'z ichiga olgan bo'lsa kerak bo'ladi (pastga qarang). Iqtibos muammosini oldini olish uchun iloji bo'lsa, ustun yoki jadval identifikatorlari sifatida zaxiralangan kalit so'zlardan foydalanishdan qochish tavsiya etiladi.

Identifikator bo'lishi mumkin bo'lmagan holat mavjud zaxiralangan kalit so'z yoki o'z ichiga oladi bo'shliq belgilari yoki cheklangan to'plamdan tashqaridagi belgilar lekin, albatta, ularning atrofida backlinks talab qiladi.

123E10 haqiqiy identifikator nomi, lekin ayni paytda yaroqli INTEGER harfidir.

[Bunday identifikator nomini qanday olishingiz haqida batafsil ma'lumot bermasdan] Aytaylik, men 123456e6 nomli vaqtinchalik jadval yaratmoqchiman.

Orqa tizmalarda XATO YO'Q.

DB > `123456e6` vaqtinchalik jadvalini yaratish (`id` char(8)); So‘rov OK, 0 qatorga ta’sir qildi (0,03 sek)

Agar siz qayta qo'ng'iroqlardan foydalanmasangiz, XATO.

DB > vaqtinchalik jadval yaratish 123451e6 (`id` char (8)); ERROR 1064 (42000): SQL sintaksisida xatolik bor; 1-qatordagi "123451e6 (`id` char (8))" yonida foydalanish uchun toʻgʻri sintaksis uchun MariaDB server versiyasiga mos keladigan qoʻllanmani tekshiring.

Biroq, 123451a6 - bu yaxshi identifikator nomi (orqa belgilarisiz).

DB > vaqtinchalik jadval yaratish 123451a6 (`id` char (8)); So‘rov OK, 0 qatorga ta’sir qildi (0,03 sek)

Buning sababi, 1234156e6 ham eksponensial sondir.

VALUES() roʻyxatidagi kabi satr qiymatlari uchun bitta tirnoq qoʻllanilishi kerak.

Orqa tig'lar odatda identifikatorni ko'rsatish uchun ishlatiladi va zahiradagi kalit so'zlarning vaqti-vaqti bilan ishlatilishi tufayli xavfsiz bo'lishi mumkin.

PHP va MySQL bilan birgalikda qo'sh tirnoq va bitta tirnoq so'rov yozish vaqtini sezilarli darajada soddalashtiradi.

MySQL-da ikki turdagi tirnoq mavjud:

  1. " string literallarini kiritish uchun
  2. ` jadval va ustun nomlari kabi identifikatorlarni kiritish uchun

Va keyin "bu alohida holat. Bu uchun foydalanish mumkin bitta serverning sql_mode rejimiga qarab bir vaqtning o'zida yuqoridagi maqsadlardan:

  1. Standart"belgi" string literallarini joylashtirish uchun ishlatilishi mumkin "
  2. ANSI_QUOTES rejimida " belgisi identifikatorlarni kiritish uchun ishlatilishi mumkin, ANSI_QUOTES

Quyidagi so'rovlar SQL rejimiga qarab turli natijalarni (yoki xatolarni) keltirib chiqaradi:

JADALDAN "ustun" ni tanlang WHERE foo = "bar"

ANSI_QUOTES o‘chirilgan

So'rov foo ustuni "bar" qatoriga teng bo'lgan "ustun" satrini tanlaydi.

ANSI_QUOTES yoqilgan

So'rov foo ustuni ustunga teng bo'lgan ustun ustunini tanlaydi

Qachon foydalanish kerak

  • Kodingiz SQL rejimlariga bog'liq bo'lmasligi uchun "" dan foydalanmaslikni tavsiya qilaman
  • Har doim identifikatorlarni qo'shing, chunki bu yaxshi amaliyotdir (SO bo'yicha bir nechta savollar buni muhokama qiladi)

"" va "" foydalanish o'rtasida aniq farq bor.

Butunlay " " ishlatilsa, "transformatsiya yoki tarjima" bo'lmaydi. U xuddi shunday chop etiladi.

" " bilan, u o'rab turgan narsa uning qiymatiga "tarjima qilinadi yoki o'zgartiriladi".

Tarjima/konvertatsiya deganda nimani nazarda tutmoqchiman: bitta tirnoq ichidagi har qanday narsa ularning qiymatlariga "tarjima" qilinmaydi. Ular qo'shtirnoq ichida bo'lgani uchun qabul qilinadi. Misol: a=23 , keyin "$a" echo standart chiqishda $a hosil qiladi. Echo "$a" esa standart chiqishda 23 ni ishlab chiqaradi.

(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_string — SQL bayonotida foydalanish uchun satrdagi maxsus belgilardan qochish

Tavsif

mysql_real_escape_string (string $unescaped_string [, resurs $link_identifier = NULL]): string

Unescaped_stringdagi maxsus belgilarni, ulanishning joriy belgilar to'plamini hisobga olgan holda, uni joylashtirish xavfsiz bo'lishi uchun chiqaradi. mysql_query(). Ikkilik ma'lumotlar kiritilishi kerak bo'lsa, bu funktsiyadan foydalanish kerak.

mysql_real_escape_string() MySQL kutubxonasi funksiyasini mysql_real_escape_string chaqiradi, u quyidagi belgilarga teskari qiyshiq chiziq qo‘yadi: \x00, \n, \r, \ , " , " va \x1a.

MySQL-ga so'rov yuborishdan oldin ma'lumotlar xavfsizligini ta'minlash uchun ushbu funktsiya har doim (bir nechta istisnolardan tashqari) ishlatilishi kerak.

Diqqat

Xavfsizlik: standart belgilar to'plami

Belgilar to'plami server darajasida yoki API funktsiyasi bilan o'rnatilishi kerak mysql_set_charset() ta'sir qilishi uchun mysql_real_escape_string() . Qo'shimcha ma'lumot olish uchun belgilar to'plamidagi tushunchalar bo'limiga qarang.

Parametrlar

unescaped_string

Qochish kerak bo'lgan qator.

Havola_identifikatori

MySQL ulanishi. Agar havola identifikatori ko'rsatilmagan bo'lsa, oxirgi havola tomonidan ochiladi mysql_connect() faraz qilinadi. Agar bunday havola topilmasa, u xuddi shunday havola yaratishga harakat qiladi mysql_connect() hech qanday dalilsiz chaqirilgan edi. Hech qanday aloqa topilmasa yoki o'rnatilmasa, an E_OGOHLANTIRISH darajadagi xatolik hosil bo'ladi.

Qaytish qiymatlari

Chiqib ketgan qatorni qaytaradi yoki FALSE xato ustida.

Xatolar/istisnolar

Ushbu funktsiyani MySQL ulanishisiz bajarish ham chiqaradi E_OGOHLANTIRISH PHP darajasidagi xatolar. Ushbu funktsiyani faqat joriy MySQL ulanishi bilan bajaring.

Misollar

1-misol oddiy mysql_real_escape_string() misol

//Ulanmoq
$link = mysql_connect("mysql_host", "mysql_user", "mysql_password")
OR o'ladi (mysql_error());

//So'rov
$query = sprintf ( "foydalanuvchilardan * ni tanlang. user="%s" VA parol="%s"",
mysql_real_escape_string($user),
mysql_real_escape_string($parol));
?>

№2 misol mysql_real_escape_string() ulanish misolini talab qiladi

Ushbu misol ushbu funktsiyani chaqirganda MySQL ulanishi mavjud bo'lmasa nima bo'lishini ko'rsatadi.

Yuqoridagi misol shunga o'xshash narsani chiqaradi:

Ogohlantirish: mysql_real_escape_string(): 5-qatorda /this/test/script.php da bunday fayl yoki katalog yoʻq Ogohlantirish: mysql_real_escape_string(): 5-qatordagi /this/test/script.php da serverga havola oʻrnatib boʻlmadi. bool(false) string(41) "SELECT * FROM aktyorlar WHERE last_name = """

3-misol SQL injection hujumiga misol

// Biz $_POST["parol"] ni tekshirmadik, bu foydalanuvchi xohlagan narsa bo'lishi mumkin! Masalan:
$_POST [ "foydalanuvchi nomi" ] = "aidan" ;
$_POST [ "parol" ] = "" YOKI ""="" ;

// Mos foydalanuvchilar mavjudligini tekshirish uchun ma'lumotlar bazasiga so'rov
$query = ( $_POST [ "foydalanuvchi nomi" ]) " VA parol=" ( $_POST [ "parol" ]) "" ;
mysql_query($query);

// Bu MySQL-ga yuborilgan so'rov quyidagicha bo'lishini anglatadi:
echo $query ;
?>

MySQL-ga yuborilgan so'rov:

Bu har kimga haqiqiy parolsiz kirish imkonini beradi.

Eslatmalar

Foydalanishdan oldin MySQL ulanishi talab qilinadi mysql_real_escape_string() aks holda daraja xatosi E_OGOHLANTIRISH hosil bo'ladi va FALSE qaytariladi. Agar link_identifier aniqlanmagan bo'lsa, oxirgi MySQL ulanishi ishlatiladi.

Eslatma: mysql_real_escape_string() qochib ketmaydi % va _ . Bu MySQL-dagi joker belgilar, agar bilan birlashtirilgan bo'lsa LIKE, Grant, yoki BEKOR QILISh.

8 yil oldin

Asl mysql_real_escape_string ga taqlid qiladigan, lekin faol MySQL ulanishini talab qilmaydigan kichik funksiya. Maʼlumotlar bazasi sinfida statik funksiya sifatida qoʻllanilishi mumkin. U kimgadir yordam beradi deb umid qilaman.

mysql_escape_mimic funktsiyasi ($inp) (
if(is_array($inp))
massiv_xaritasini qaytarish (__METHOD__ , $inp );

If(!empty($inp ) && is_string ($inp )) (
return str_replace (massiv("\\" , "\0" , "\n" , "\r" , """ , """ , "\x1a" ), massiv("\\\\" , "\ \0" , "\\n" , "\\r" , "\\"", "\\"" , "\\Z" ), $inp );
}

$inp ni qaytaring;
}
?>

13 yil oldin

E'tibor bering, mysql_real_escape_string hujjatda aytib o'tilganidek, \x00, \n, \r va \x1a ga teskari qiyshiq chiziq qo'ymaydi, lekin aslida belgini so'rovlar uchun MySQL-ning maqbul ko'rinishi bilan almashtiradi (masalan, \n "\" bilan almashtiriladi. n" literal). (\, ", va " hujjatlashtirilganidek o'chirilgan) Bu funksiyadan qanday foydalanishni o'zgartirmaydi, lekin men buni bilish yaxshi deb o'ylayman.

6 yil oldin

Hech kimga talqin qilingan kodni yaratish uchun tashqi ma'lumotlardan foydalanmaslik kerakligini aytmasdan, qochish haqida hech qanday muhokama tugamaydi. Bu SQL iboralari yoki siz har qanday "baholash" funksiyasini chaqiradigan har qanday narsaga tegishli.

Shunday qilib, bu dahshatli buzilgan funktsiyadan foydalanish o'rniga, o'rniga parametrik tayyorlangan bayonotlardan foydalaning.

Rostini aytsam, SQL bayonotlarini tuzish uchun foydalanuvchi tomonidan taqdim etilgan ma'lumotlardan foydalanish professional beparvolik hisoblanishi kerak va siz parametrik tayyorlangan bayonotlardan foydalanmaganligingiz uchun ish beruvchingiz yoki mijozingiz tomonidan javobgarlikka tortilishi kerak.

U nimani anglatadi?

Bu shunday SQL iborasini yaratish o'rniga:

"X (A) VALUES INSERT INTO (".$_POST["a"].)"

Quyidagi kabi ko'rinishdagi iborani bajarish uchun MySQli-ning tayyorlash() funktsiyasidan () foydalanishingiz kerak:

"X (A) QIMMATLARGA (?) QO'RISH"

Eslatma: Bu siz hech qachon dinamik SQL bayonotlarini yaratmasligingiz kerak degani emas. Bu shuni anglatadiki, siz ushbu bayonotlarni yaratish uchun hech qachon foydalanuvchi tomonidan taqdim etilgan ma'lumotlardan foydalanmasligingiz kerak. Foydalanuvchi tomonidan taqdim etilgan har qanday ma'lumotlar bayonotga parametr sifatida uzatilishi kerak. tayyorlangan.

Masalan, agar siz kichik ramka yaratmoqchi bo'lsangiz va URI so'rovi asosida jadvalga qo'shimcha kiritmoqchi bo'lsangiz, $_SERVER["REQUEST_URI"] qiymatini (yoki boshqa har qanday) qabul qilmaslik sizning manfaatingiz uchundir. qismi) va uni soʻrovingiz bilan toʻgʻridan-toʻgʻri bogʻlang. Buning oʻrniga, siz xohlagan $_SERVER["REQUEST_URI"] qiymatining qismini ajratib koʻrsatishingiz va uni qandaydir funksiya yoki assotsiativ massiv orqali foydalanuvchi boʻlmagan bilan taqqoslashingiz kerak. Agar xaritalash hech qanday qiymat bermasa, foydalanuvchi taqdim etgan maʼlumotlarda nimadir notoʻgʻri ekanligini bilasiz.

Bunga rioya qilmaslik Ruby On Rails tizimida parametrik tayyorlangan bayonotlardan foydalansa ham, bir qator SQL in'ektsiya muammolariga sabab bo'ldi. GitHub bir vaqtning o'zida shunday buzildi. Demak, hech bir til bu muammodan himoyalanmagan. Shuning uchun bu PHP uchun xos narsa emas, balki umumiy eng yaxshi amaliyot va nima uchun uni HAQIQATDA qabul qilishingiz kerak.

Bundan tashqari, siz parametrik tayyorlangan bayonotlardan foydalanganda ham foydalanuvchilar tomonidan taqdim etilgan ma'lumotlarni tekshirishni amalga oshirishingiz kerak. Buning sababi shundaki, foydalanuvchi tomonidan taqdim etilgan ma'lumotlar ko'pincha yaratilgan HTMLning bir qismiga aylanadi va siz foydalanuvchi taqdim etgan ma'lumotlar brauzerda xavfsizlik muammolariga olib kelmasligiga ishonch hosil qilishni xohlaysiz.

9 yil oldin

2-misolda SQL in'ektsiyasi haqida qiziqarli jihat bor: AND OR dan ustun turadi, shuning uchun kiritilgan so'rov aslida QAYER (foydalanuvchi = "aidan" VA parol = "") YOKI ""="" sifatida bajariladi. ixtiyoriy foydalanuvchi nomiga (bu holda "aidan") mos keladigan ma'lumotlar bazasi yozuvini qaytarish uchun, u aslida HAMMA ma'lumotlar bazasi yozuvlarini qaytaradi. Hech qanday aniq tartibda emas. Shunday qilib, tajovuzkor istalgan hisob sifatida kirishi mumkin, lekin har qanday hisob qaydnomasi bilan kirishi shart emas. qaysi hisob ekanligini nazorat qilish.

Albatta, potentsial hujumchi o'z parametrlarini qiziqtirgan foydalanuvchilarga yo'naltirish uchun o'zgartirishi mumkin:

//Masalan. tajovuzkorning qadriyatlari
$_POST [ "foydalanuvchi nomi" ] = "" ;
$_POST["parol"] = "" YOKI foydalanuvchi = "administrator" VA "" = "";

// Noto'g'ri tuzilgan so'rov
$so'rov = "FROM * foydalanuvchilar QAYERDA foydalanuvchi" ni tanlang.$_POST [ foydalanuvchi nomi ] " VA parol=" $_POST [ parol ] "" ;

echo $query ;

// MySQL-ga yuborilgan so'rov o'qiydi:
// Foydalanuvchilardan * TANLASH QAYERDA user="" VA password="" YOKI user="administrator" VA ""="";
// bu har kimga "administrator" deb nomlangan hisobga kirishga ruxsat beradi

?>

1 yil oldin

@feedr
Men uning eslatmasini quyidagicha ishlab chiqdim:
$string = "asda\0sd\x1aas\\\\\\\\dasd\"asdasd\na\"\"sdasdad";
$massiv1 = massiv("\\\\\\\\", "\0", "\n", "\r", """, """, "\x1a");
$massiv2 = massiv("\\\\\\\\\\\\\\\\", "\\\0", "\\\n", "\\\r", "\\\ " ", "\\\"", "\\\ Z");
echo($string);
echo (PHP_EOL);
uchun($i=0; $i agar ($i==0)
$p = "/(?boshqa
$p = "/(?echo($i);
echo($p);
echo($massiv2[$i]);
$string = preg_replace($p, $massiv2[$i], $string);
echo("\t");
echo($string);
echo (PHP_EOL);
}
echo (PHP_EOL);
echo($string);

2 yil oldin

Numb Safari-da Semdan iqtibos keltirish uchun

[ "Qochish boʻyicha hech qanday munozara hammaga talqin qilingan kodni yaratish uchun hech qachon tashqi maʼlumotlardan foydalanmaslik kerakligini aytmasdan turib tugamaydi. Bu SQL iboralari yoki siz har qanday "baholash” funksiyasini chaqiradigan har qanday narsaga tegishli.

Shunday qilib, bu dahshatli buzilgan funktsiyadan foydalanish o'rniga, o'rniga parametrik tayyorlangan bayonotlardan foydalaning.

Rostini aytsam, SQL bayonotlarini tuzish uchun foydalanuvchi tomonidan taqdim etilgan ma'lumotlardan foydalanish professional beparvolik hisoblanishi kerak va siz parametrik tayyorlangan bayonotlardan foydalanmaganingiz uchun ish beruvchingiz yoki mijozingiz tomonidan javobgarlikka tortilishi kerak." ]

Sem haq.......

Biroq, men barcha tozalashni to'xtatish va vazifani parametrik tayyorlangan bayonotlarga topshirishni oqilona deb o'ylamayman.

Muayyan vaziyatda ishlaydigan muayyan ishlab chiquvchi har doim to'g'ri kiritish haqida ko'proq ma'lumotga ega bo'ladi (shu kontekstga xos).

Agar siz foydalanuvchidan ularga allaqachon bergan qiymatni kiritishni so'rasangiz va siz bunday qiymatlarning barchasi AB****** dan boshlanishini va satr uzunligi 7 yoki 11 bo'lishi kerakligini bilsangiz, lekin hech qachon boshqa uzunlik bo'lmasligi kerak. yaxshi dezinfektsiyalash vositasining asosi - qatorning ruxsat etilgan turli uzunliklari eski ma'lumotlarni ko'rsatishi mumkin.

Men hech qachon yomon niyatli foydalanuvchi forma orqali yuborgan axlatni parametrik tayyorlangan bayonotlarga o'tkazishni xohlamayman, men har doim birinchi navbatda o'zimning aql-idrokimni tekshirishni xohlayman va ba'zi hollarda ular ehtiyotkorona xato qilishi mumkin. shunchaki ma'lumotlar bazasi opsiyasini butunlay bekor qilishni tanlang.

Shunday qilib, mening ma'lumotlar bazasi xavfsiz bo'lgan xavfsiz bayonotlar bilan tiqilib qolmaydi - u shunchaki tiqilib qolmaydi, qaysi biri yaxshiroq.

Qatlamlardagi xavfsizlik - tayyorlangan bayonotlardan foydalanishdan oldin har qanday vaziyatda sanitariya va tekshirishni hisobga olish kerak.

Bundan tashqari, men rasmiy hujjatni o'qishim mumkin
==============================================

"Qochish va SQL in'ektsiyasi

Bog'langan o'zgaruvchilar serverga so'rovdan alohida yuboriladi va shuning uchun unga aralasha olmaydi. Server ushbu qiymatlardan to'g'ridan-to'g'ri bajarilish nuqtasida, bayonot shablonini tahlil qilgandan so'ng foydalanadi. Bog'langan parametrlardan qochish shart emas, chunki ular hech qachon so'rovlar qatoriga to'g'ridan-to'g'ri almashtirilmaydi"

Bu menga shuni ko'rsatadiki, ichki organlardagi xavf bekor qilish bilan emas, balki muqobil ishlov berish orqali oldini oladi.

Bu shuni anglatadiki, tayyorlangan bayonotlarga to'liq o'tkazilmagan katta loyiha, tashkilotning turli qismlaridagi eski kod yoki bir-biri bilan gaplashadigan serverlar yomon yangiliklarni immunitetga ega bo'lgan joydan yoki vaziyatdan immunitetga ega bo'lmagan joyga etkazishi mumkin.

Sanitariya qo'shimcha xavf tug'dirmasdan to'g'ri bajarilgan ekan, men shaxsan ma'lum bir dezinfektsiyalash qatlamlariga rioya qilaman va keyin tayyorlangan bayonotlarni chaqiraman.


Birinchidan, bu slashlar nima uchun umuman kerakligi haqida bir oz.
Agar biz so'rovda biron bir ma'lumotni almashtirsak, bu ma'lumotlarni SQL buyruqlaridan farqlash uchun ularni qo'shtirnoq ichiga qo'yish kerak.
Misol uchun, agar siz yozsangiz
SELECT * FROM jadval QAYERDA nomi = Bill
keyin ma'lumotlar bazasi Bill boshqa maydonning nomi ekanligiga qaror qiladi, uni topa olmaydi va xatoga yo'l qo'yadi. Shuning uchun almashtirilgan ma'lumotlar (bu holda, Bill nomi) qo'shtirnoq ichiga olinishi kerak - keyin ma'lumotlar bazasi uni satr deb hisoblaydi, uning qiymati nom maydoniga tayinlanishi kerak:
SELECT * FROM jadval QAYERI nomi = "Hisob-kitob"
Biroq, tirnoqlar ma'lumotlarning o'zida ham paydo bo'lishi mumkin. Masalan,
TANLOV * JadvalDAN QAYERI nomi = "D"Artagnan"
Bu erda ma'lumotlar bazasi "D" - bu ma'lumotlar, Artagnan esa u bilmagan buyruq va xatoga yo'l qo'yadi. Shuning uchun ma'lumotlar bazasiga ulardagi tirnoq belgilari (va ba'zi boshqa maxsus belgilar) ma'lumotlarga tegishli ekanligini tushuntirish uchun barcha ma'lumotlarni kuzatib borish kerak.
Natijada, biz xatolikka olib kelmaydigan to'g'ri so'rovni olamiz:
TANLOV * jadvaldan WHERE nomi = "D\"Artagnan"

Shunday qilib, biz so'rovga satr ma'lumotlarini almashtirishda ikkita qoidaga rioya qilish kerakligini aniqladik:
- barcha kiritilgan qator ma'lumotlari qo'shtirnoq ichiga olinishi kerak (bitta yoki ikkita, lekin bittasi qulayroq va tez-tez ishlatiladi).
- maxsus belgilardan slash bilan qochish kerak.

Shuni alohida ta'kidlash kerak: qo'shilgan slashlar ma'lumotlar bazasiga kirmaydi. Ular faqat so'rovda kerak bo'ladi. Poydevorga urilganda slashlar tashlanadi. Shunga ko'ra, keng tarqalgan xato - ma'lumotlar bazasidan ma'lumotlarni olishda chiziqli chiziqdan foydalanish.

Yuqorida aytilganlarning barchasi qator ma'lumotlari va sanalar uchun amal qiladi. Raqamlar orqasidan yoki qo'shtirnoq bilan o'ralgan holda kiritilishi mumkin. Agar shunday qilsangiz ZARUR! Ma'lumotni so'rovga kiritishdan oldin kerakli turga majburlang, masalan:
$id = intval ($id);
Biroq, soddaligi (va ishonchliligi) uchun siz raqamlar bilan xuddi satrlar bilan ishlashingiz mumkin (chunki MySQL hali ham ularni kerakli turga o'zgartiradi). Shunga ko'ra, biz so'rovga kiritilgan har qanday ma'lumotlarni kuzatib boramiz va uni qo'shtirnoq ichiga olamiz.

Bundan tashqari, yana bitta qoida mavjud - ixtiyoriy, ammo xatolarga yo'l qo'ymaslik uchun unga rioya qilish kerak:
Имена полей и таблиц следует заключать в обратные одинарные кавычки - "`" (клавиша с этим символом находится на стандартной клавиатуре слева от клавиши "1") Ведь имя поля может совпадать с ключевыми словами mysql, но если мы используем обратную кавычку, то MySQL поймёт hammasi to'g'ri:
* `Jadval` QAYERDA `sana` = "2006-04-04" NI TANLASH
Siz bu qo'shtirnoqlarni bir-biridan farqlashingiz va birini boshqasi bilan aralashtirib yubormasligingiz kerak. Shuni ham yodda tutish kerakki, orqa tirgaklar slashlardan qochib qutula olmaydi.

Shunday qilib, biz so'rovga ma'lumotlarni qanday qilib to'g'ri almashtirishni o'rgandik.
LEKIN! Dinamik so'rovlarni qurish faqat ma'lumotlarni almashtirish bilan cheklanmaydi. Ko'pincha biz so'rovda SQL buyruqlari va maydon nomlarini almashtirishimiz kerak. Va bu erda biz xavfsizlik mavzusiga o'tamiz:

SQL Injection - bu skriptga o'tkazilgan ma'lumotlar shu skriptda yaratilgan so'rov mo'ljallanganidan butunlay boshqacha ishni bajarishni boshlaydigan tarzda o'zgartirilganda xakerlik hujumi usuli.
Bunday hujumlardan himoya qilish qoidalarini ikki nuqtaga bo'lish mumkin:
1. Ma'lumotlar bilan ishlash.
2. So'rovlarni boshqarish elementlari bilan ishlash.

Biz yuqorida birinchi fikrni batafsil muhokama qildik. Aytish mumkinki, bu, aslida, himoya emas. So'rovga ma'lumotlarni qo'shish qoidalariga rioya qilish, birinchi navbatda, SQL SYNTAX talablari bilan belgilanadi. Va nojo'ya ta'sir sifatida bizda xakerlikdan himoyalanish ham mavjud.

Ikkinchi nuqta ancha qiyin, chunki ma'lumotlarga nisbatan yagona universal qoida yo'q - teskari belgi maydon nomini xaker tomonidan o'zgartirilishidan himoya qilmaydi. Jadval nomlarini, SQL bayonotlarini, LIMIT buyruq parametrlarini va boshqa bayonotlarni himoya qilish uchun tirnoqlardan foydalanish mumkin emas.
Shuning uchun so'rovga boshqaruv elementlarini almashtirishda asosiy qoida:
Agar siz so'rovga SQL iboralarini yoki maydonlar, ma'lumotlar bazalari, jadvallar nomlarini dinamik ravishda kiritishingiz kerak bo'lsa, hech qanday holatda ularni to'g'ridan-to'g'ri so'rovga kiritmasligingiz kerak.
Bunday qo'shimchalar uchun barcha variantlar skriptingizda ADVANCE da yozilishi va foydalanuvchi kiritgan narsaga qarab tanlanishi kerak.
Misol uchun, agar siz operator tomonidan buyurtmaga maydon nomini kiritishingiz kerak bo'lsa, unda hech qanday holatda uni to'g'ridan-to'g'ri almashtirmasligingiz kerak. Avval tekshirishimiz kerak. Masalan, yaroqli qiymatlar massivini tuzing va uni so‘rovga faqat o‘tkazilgan parametr ushbu massivda mavjud bo‘lsagina almashtiring:
$orders =massiv("nom" , "narx" , "qty" );
$key = array_search($_GET["sort"], $orders));
$orderby = $buyurtmalar [ $key ];
$so'rov = "Jadvaldan * NI BUYURTISH BO'YICHA TANlang$orderby ";

Biz foydalanuvchi tomonidan kiritilgan so'z uchun oldindan tavsiflangan variantlar qatorini qidiramiz va agar topsak, massivning mos keladigan elementini tanlaymiz. Agar moslik topilmasa, massivning birinchi elementi tanlanadi.
Shunday qilib, so'rovda o'zgartirilgan narsa foydalanuvchi kiritgan narsa emas, balki bizning skriptimizda yozilgan narsadir.
Boshqa barcha holatlarda ham xuddi shunday qilish kerak.
Masalan, WHERE bandi dinamik ravishda yaratilgan bo'lsa:
agar (!empty($_GET [ "narx" ])) $qaerda .= "price="" . mysql_real_escape_string ($_GET [ "narx" ]). """ ;
$query = "SELECT * FROM `jadval` WHERE $where " ;

Jadval nomini so'rovga dinamik ravishda kiritish mumkin bo'lgan holatni tasavvur qilish men uchun qiyin, lekin agar bu sodir bo'lsa, unda nom faqat skriptda oldindan belgilangan to'plamdan kiritilishi kerak.
LIMIT operatorining parametrlari arifmetik amallar yoki intval() funksiyasi yordamida butun son turiga majburlanishi kerak.
Bu erda keltirilgan misollar dinamik so'rovlarni qurish uchun barcha variantlarni tugatadi deb o'ylamang. Siz faqat printsipni tushunishingiz va barcha bunday holatlarda qo'llashingiz kerak.

Mening ishimning tabiati tufayli men veb-ilovalar manba kodining xavfsizlik tekshiruvlarini o'tkazishim kerak.
Ko'plab veb-ilovalar va juda ko'p kodlar ...

Hech kimga sir emaski, SQL injection zaifliklari server tomonidagi veb-ilovalarning barcha zaifliklari ichida eng keng tarqalgani hisoblanadi. Bunday narsalar deyarli butunlay chiqarib tashlangan platformalar va ramkalar mavjud, masalan, ORM va boshqalar.Lekin statistika bizga Internetda oddiy birlashtirilgan SQL so'rovlari bilan veb-ilovalarning mutlaq ustunligi haqida doimiy ravishda aytib beradi.Bundan tashqari, ORM bo'lgan holatlar mavjud. Umuman qo'llanilishi mumkin, masalan, nafaqat iboralar parametrlari, balki operator darajasidagi so'rovlar mantig'ining o'zi ham foydalanuvchi ma'lumotlariga bog'liq bo'lishi kerak.

Shunday ekan, boshlaylik.

Foydasiz xarakterdan qochish
PHP veb-ilovalarining 83 foizida SQL in'ektsiyasidan himoyasiz bo'lgan
Kabi belgilar uchun qochish funksiyasidan foydalanish
mysql_escape_string
mysql_real_escape_string
qiyshiq chiziqlar
tirnoqsiz. Ko'pincha u raqamli parametrlarda (barcha turdagi * _id) namoyon bo'ladi.
Misol
$sql = "FROM foydalanuvchilar ro'yxatidan foydalanuvchini tanlang WHERE userid=".mysql_real_escape_string($_GET["uid"]);

Bu xavfsiz kod kabi ko'rinadi, lekin faqat sirtda. Mening amaliyotimda PHP-da SQL in'ektsiyalarining eng keng tarqalgan namunasi shu erda joylashgan. Ushbu zaiflikka hujum qilish uchun tajovuzkor hujum vektorida " " \x00 \r \n \x1a belgilaridan foydalanishdan qochishi kerak.
Masalan:
/index.php?uid=-777 UNION SELECT parolini foydalanuvchilar roʻyxatidan

Kodda qidirish
Tilning semantikasi bilan murakkablashgan. Oddiy qidiruv uchun siz egrep dan foydalanishingiz mumkin:
egrep -Rin "(tanlang|yangilash|qo'shish|o'chirish|almashtirish).*(dan|o'rnatish|ichiga).*(mysql_escape_string|mysql_real_escape_string|qo'shimchalar)" . | grep -v "[\""]["\"]"

Qidiruv ifodasining mantig'i quyidagicha: filtrlash funktsiyalarining chap tomonida tirnoq belgilari ketma-ketligi ("", "", "", "") bo'lmagan barcha qatorlarni toping. Usul, albatta, 100% dan uzoqdir, ammo semantik tahlilni amalga oshirish uchun muntazam ifodani talab qilish mumkin emas.
Ma'lumotni ko'rsatishni osonlashtirish uchun siz konsolda funksiyani rang bilan ajratib ko'rsatishingiz mumkin:
egrep -Rin "(tanlang|yangilash|qo'shish|o'chirish|almashtirish).*(dan|o'rnatish|ichiga).*(mysql_escape_string|mysql_real_escape_string|qo'shimchalar)" . | grep -v "[\""]["\"]" | egrep --color "(mysql_escape_string|mysql_real_escape_string|qo'shimchalar)"

Ushbu joker belgilar zaifligidan himoya qilish uchun turdagi castingdan foydalanish yaxshidir.
Bu har doim filtrlash va skrining barcha turlariga qaraganda tezroq ishlaydi va ishonchliroq.
Yuqoridagi misol uchun yamoq quyidagicha bo'lishi mumkin:
$sql = "FROM foydalanuvchilar ro'yxatidan foydalanuvchini tanlang WHERE userid=".intval($_GET["uid"]);

Bu qisqa inshoni yakunlaydi. Men barcha veb-ishlab chiquvchilarni bunday dizaynlar uchun manbalarini tekshirishga chaqiraman. Yaxshisi, odamlar uchun berilgan qidiruv skriptini kengaytiring.

Shunday qilib, men MySQL va PHP sohalarini chuqur o'rganib chiqdim... xususan, ma'lumotlar bazasi va shakl kiritishlari bilan ishlashda qo'llashim kerak bo'lgan xavfsizlik choralari. Hozirgacha men quyidagilarni juda tavsiya etilgan deb topdim:

  1. Tayyorlangan bayonotlar
  2. _real_escape_string() dan foydalanish
  3. Sehrli tirnoqlardan foydalanmang, chunki u ma'lumotlar bazalarini chalkashtirib yuboradi va "Siz uni chaqirmadingiz ..." kabi narsalarni beradi.

Bularning barchasi ajoyib va ​​men buni kuzatib boraman. Biroq, men dollar belgisi [$], foiz belgisi [%] va ehtimol boshqalar kabi belgilardan qochishim kerakmi, deb hayron bo'ldim. So'rov dollar belgisini PHP o'zgaruvchisi sifatida talqin qilishi mumkinmi? Men eshitgan LIKE sintaksisi % belgisi yoki hatto joker belgidan foydalanishi haqida nima deyish mumkin? Tayyorlangan bayonotlar texnik jihatdan bularning barchasiga g'amxo'rlik qilishi kerak, lekin men xavfsiz tomonda bo'lishni va hamma narsani to'g'ri yoritganimga ishonch hosil qilishni xohlardim. Men tayyorlangan bayonotlardan foydalanishni unutib qo'ysam yoki ularni e'tiborsiz qoldirgan hollarda, men ushbu ikkinchi himoya chizig'i bosh aylanishidan xalos bo'lishimni aytishi mumkin deb umid qildim.

Hozir men qochish uchun foydalanayotgan narsam:

Funktsiyadan qochish($connection, $data)( $new_data = trim($data); $new_data = i_real_escape_string($connection, $new_data); $new_data = addcslashes($new_data, "%_$"); $new_data = htmlspecialchars ($new_data, ENT_NOQUOTES); qaytarish $new_data; )

Xo'sh, bu to'g'rimi? Men juda noto'g'ri ish qilyapmanmi? E'tibor bering, ma'lumotlar bazasi ma'lumotlarini qaytarishda $,% va _ belgilar oldidagi teskari chiziqni olib tashlashim kerak.

Men juda noto'g'ri ish qilyapmanmi?

Avval tadqiqotingiz haqida.

Tayyorlangan bayonotlar - yagona siz topgan ajoyib narsa.

Garchi mysqli_real_escape_string dan foydalanish (tayyorlangan bayonotlardan foydalanayotgan bo'lsangiz) bo'ladi foydasiz va zararli(o'zingiz qayd etgan natijani yaratish: "Siz qo'ng'iroq qildingiz ...").

Sehrli iqtiboslar tildan uzoq vaqtdan beri olib tashlangan - shuning uchun hech narsaga arzimaydi.

Shunday qilib, hatto boshlang'ich binolaringizning aksariyati noto'g'ri.

Endi savolingizga.

So'rov dollar belgisini PHP o'zgaruvchisi sifatida talqin qilishi mumkinmi?

Men eshitgan LIKE sintaksisi % belgisi yoki hatto joker belgidan foydalanishi haqida nima deyish mumkin?

Ha, siz buni to'g'ri eshitdingiz. LIKE operatorining aniq maqsadi naqsh qidirishni amalga oshirishdir. LIKE-da bu belgilarni o'chirib qo'yish zarracha ma'noga ega bo'lmaydi.

Har safar LIKE operatoridan foydalanmoqchi bo'lganingizda, qaysi belgidan foydalanishni va qaysi birini taqiqlashni hal qilishingiz kerak. Siz bir martalik yechimdan foydalana olmaysiz. Boshqa barcha MySQL o'zaro aloqalarida % belgisi alohida ma'noga ega emasligini eslatib o'tmaslik kerak.

Tayyorlangan bayonotlar texnik jihatdan bularning barchasiga g'amxo'rlik qilishi kerak

Tayyorlangan bayonotlarning $ yoki % belgilariga aloqasi yo'q. Tayyorlangan iboralar SQL in'ektsiyasiga ishora qiladi, lekin hech qanday belgi uni keltirib chiqara olmaydi (siz "in'ektsiya" ni to'g'ri qo'llaniladigan LIKE operatori deb atay olmaysiz, shunday emasmi?).

Nihoyat, eng yomon qismiga.

Agar siz tayyorlangan bayonotlardan foydalanishni unutib qo'ysangiz yoki ularga amal qilishni e'tiborsiz qoldirsangiz,

sizni hech narsa qutqarmaydi.

Va eng kam yordam siz ishlab chiqqan funksiyadan bo'ladi.

Xulosa qiling.

  1. Ushbu xususiyatdan xalos bo'ling.
  2. Foydalanish plomba moddalari * so'rovda har bir alohida o'zgaruvchini ko'rsatish uchun.
  3. Kiritishdagi % va _ belgilaridan faqat LIKE operatorida foydalanilsa va ularning talqin qilinishini istamasangiz, qochishingiz mumkin.
  4. Chiqish uchun MySQL kiritish emas, htmlspecialchars() dan foydalaning.

*agar bu atama sizga notanish bo'lsa, tayyorlangan bayonotlarni o'qing.

Dollar belgisidan qochishingiz shart emas. MySQL bu belgiga alohida qaramaydi va PHP uni satr qiymatlarida emas, faqat manba kodida taniydi (agar siz satrda eval ni chaqirmasangiz, lekin bu butunlay boshqa qurt qurtidir).

Agar siz LIKE argumenti sifatida foydalanuvchi kiritishidan foydalansangiz va foydalanuvchi joker belgilardan foydalana olishini xohlamasangiz, % va _ dan qochishingiz kerak bo'ladi. Agar qidiruv formasini qayta ishlayotgan bo'lsangiz, bu sodir bo'lishi mumkin. Ma'lumotlar bazasida saqlashda undan foydalanish shart emas.

Ma'lumotlar bazasiga kirishda htmlspecialchars dan foydalanish shart emas. Bu XSS in'ektsiyasini oldini olish uchun faqat HTML sahifasida foydalanuvchiga ma'lumotlarni ko'rsatishda ishlatilishi kerak.

Qaysi ma'lumotlar va nima uchun ishlatilishiga bog'liq.

Agar siz PHP-ning standart so'rovlari juda katta va murakkab deb topsangiz, soddalashtirilgan so'rovlar haqida tasavvurga ega bo'lish uchun github-da mavjud bo'lgan ba'zi sinflarni ko'rib chiqishni taklif qilaman.

Ushbu sinf bilan so'rovlarni kiritish misoli

$data = Massiv ("login" => "admin", "faol" => rost, "firstName" => "Jon", "familiya" => "Doe", "parol" => $db->func( "SHA1(?)", Massiv ("maxfiy parol+tuz")), // parol = SHA1("maxfiy parol+tuz") "createdAt" => $db->now(), // createdAt = NOW() " exires" => $db->now("+1Y") // muddati tugaydi = NOW() + interval 1 yil // Qo'llab-quvvatlanadigan intervallar [s]sekund, [m]inute, [h]soat, [d]kun, [M]onth, [Y]ear); $id = $db->insert("foydalanuvchilar", $ma'lumotlar); agar ($id) echo "foydalanuvchi yaratilgan bo'lsa. Id=" . $id; else echo "qo'shish muvaffaqiyatsiz tugadi:" . $db->getLastError();