Как да предпазим сайта си от MySQL инжекция?
В миналата статия започнахме темата с интернет инжекциите и днес ще разгледаме какво представлява инжектирането на вреден код в базата данни и как да се защитим от тази атака.
В миналата статия не го казах директно, но ще го направя сега: никога не оставяйте потребителите да въвеждат свободно информация през адресната лента на браузера и формите във вашия сайт – за коментар, имейл, регистрация и т.н.
Филтриране на въведената инфромация
Информацията от всяко поле трябва да се обработва от собствен филтър съобразно целта и вида на събираната информация.
Ако в полето трябва да се въведе телефонен номер, филтъра трябва да разрешава само арабски цифри.
Ако в полето се въвежда имейл адрес, филтъра трябва да потвърди, че е въведен само един синтактично коректен имейл адрес.
В полето за коментари филтъра трябва да замени специалните символи с техните ASCII заместители и да постави обратна наклонена черта пред единични и двойни кавички (escaping).
Филосфията е същата като заключването на външната врата на дома – всеки си заключва къщата вместо да се надява, че само добри хора ще влизат през тази врата.
Защо в интернет тази толкова очевидна практика се пренебрегва, аз лично нямам отговор, по-скоро няма да го напиша.
Подобни неща не трябва да ви се случват
Някой от читателите може би ще се изкуши да си помисли: този Иван го гони яко параноята.
Размисли пак по темата за моята параноя като прочетеш следното:
Най-голямата афера с кражба на 45 милиона номера на кредитни карти, довела до загуби за около 200 милиона долара за компанията TJX и дъщерни компании е причинена от ползване на некриптирана безжична интернет връзка и същата тази беззъба (както ще се увериш след малко) mysql инжекция.
Някой си е отворил новия лаптоп в тузарското кафене в Амстердам и е решил да си прегледа баланса на банковата сметка, не е забелязал другия клиент с лаптоп в ъгъла и ... е бръкнал в торбата с грешките.
Така че, по-добре прочети тези статии внимателно и направи това, което ти препоръчаме, преди да установиш, че си спонсорирал местните хакери с няколко хилядарки.
Да се върнем на темата с MySQL инжекцията.
Уникалното в случая е, че за да успее тази инжекция трябва да има двоен пропуск от страна на скрипта:
1. не се филтрира информацията, въведена от потребителя във формата.
2. не се добавят обратна наклонена черта пред кавичките когато се записва информацията в базата данни.
На този адрес може да намерите много примери за MySQL атаки ( статията е на английски език):
http://www.unixwiz.net/techtips/sql-injection.html
Защо не трябва да се използва РНР функцията magicquotesgpc ?
Поради следните причини:
• Несигурност - никога не можете да сте сигурни функцията дали е on или off
• Производителност – не цялата информация от формите е предназначена за импортиране в база данни, така че системата извършва ненужна работа. В този случай ползването на функцията addslashes() е за предпочитане.
• Некоректност – неприятно впечатление прави четенето на текст (например в имейл, или коментар), който е пълен с обратно наклонени черти (escaping) преди всяка кавичка – корекцията на този недостатък на *magicquotesgpc() изисква допълнителна интензивна употреба на stripslashes*().
Т.е. ефекта от употребата на тази функция предизвиква много повече проблеми, отколкото реално решава – затова и от версия 4.2. на РНР функцията е по подразбиране изключена (off), a от версия 5.3 не се поддържа изобщо.
За мен е необяснимо, че дори сега клиенти ни пишат да активираме функцията защото тяхната програма давала грешка при инсталацията.
Едно такова писмо от клиент за съпорта означава 90% сигурна работа в бъдеще с този сайт поради ползването на очевидно стара и компрометирана по отношение на сигурността програма и по-лошо – поради нежеланието на уебмастера да се движи в синхрон с актуалните интернет тенденции.
И така, нека завършим темата със защита от mysql инжекция – решението е обидно елементарно и се свежда до ползването на готова PHP функция - *mysqlrealescape_string*().
Ще ви дам и една много полезна комбинирана функция, която първо проверява дали е активирана *magicquotesgpc() и ако да, втора функция stripslashes() възстановява въведената информация като изтрива символите (escaping). Накрая фунцията mysqlrealescape_string*() приготвя текста за въвеждане в базата данни като прави mysql инжекцията невъзможна.
Ето и самата функция:
function clean($str) {
$str = @trim($str);
if(getmagicquotesgpc()) {
$str = stripslashes($str);
}
return mysqlrealescapestring($str);
}
и начинът, по който се използва при регистрация на нов потребител:
function clean($str) {
$str = @trim($str);
if(getmagicquotesgpc()) {
$str = stripslashes($str);
}
return mysqlrealescapestring($str);
}----------
$name = clean($POST['name']);
$password = clean($POST['password']);
$qry = "INSERT INTO members(name, passwd) VALUES('$name', '".sha1($password)."')";
Всяка от горните променливи, постъпващи от регистрационната форма е дефинирана и спокойно може да се въведе в базата данни (разбира се, това не е пълен код, а само пример).
Към тези променливи може да се приложат и филтри според вида на очакваната коректна информация, които подробно разгледахме в статията за предпазване от email инжекция.
Надявам се, че информацията в тази статия ви е била полезна.