Задать вопрос

Защита от SQL inj

Привет всем.
Возник такой вопрос — является ли достаточной такая фильтрация от sql inj?
foreach($_REQUEST as $_ind => $_val) {
$_REQUEST[$_ind] = mysql_real_escape_string($_REQUEST[$_ind]);
}

foreach($_POST as $_ind => $_val) {
$_POST[$_ind] = mysql_real_escape_string($_POST[$_ind]);
}

foreach($_GET as $_ind => $_val) {
$_GET[$_ind] = mysql_real_escape_string($_GET[$_ind]);
}

foreach($_COOKIE as $_ind => $_val) {
$_COOKIE[$_ind] = mysql_real_escape_string($_COOKIE[$_ind]);
}


Этот кусок кода инклудится в самом начале каждого скрипта. PHP 5.3.8
  • Вопрос задан
  • 3694 просмотра
Подписаться 5 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 9
Melkij
@Melkij
PostgreSQL DBA
Поздравляю, вы изобрели Magic Quotes.

Да, этого достаточно. Разве ещё только $_FILES необработан.
Нет, это неудобно. Из-за чего от магических кавычек и отказались.
Ответ написан
Говнокод детектед?
Интересно, как будете сравнивать значения в PHP? Например Если Вам понадобится сравнить два стринга а один из них будет изменен уже через вашу функцию(mysql_real_escape_string).
Эта функция должна вызыватся над стрингами непосредственно перед вложением в базу данных.
И вообще, хватит использовать старый mysql! Используйте mysqli: cz.php.net/manual/en/mysqli.prepare.php! Познакомтесь с препаре стейтментами и ваш геморой уйдёт в прошлое.
Ответ написан
@Elkaz
Use PDO, Luke :)
Ответ написан
Комментировать
Vladson
@Vladson
И опять мифическая «защита»…

Проснитесь люди, от «SQL-inj» надо не защищаться, это не угроза. Наличие SQL-дыр это простой баг. Хотите избежать, не допускайте ошибок в коде.

Каким путём вы передаёте данные в запрос дело ваше, можно даже с помощью bin2hex
SELECT * FROM `table`
WHERE `word`=0x4841434b454420425920564c4144534f4e;

(хотя есть способы и проще и логичнее)
Главное поймите что данные и то что SQL сервер воспримет за данные, это разные вещи.

Но перестаньте называть это защитой, это не защита, а просто «код без бага».
(Защита подразумевает угрозу которая существует даже в случае грамотного, как в случае с DDOS это вполне нормальные пакеты, только их много.)
Ответ написан
Eirenliel
@Eirenliel
Используйте mysql_real_escape_string при подстановке переменной в каждом запросе.

Извиняюсь, не умею отвечать на Хабре...
Ответ написан
Комментировать
mapron
@mapron
если есть пхп 5.3 (а не пхп4), то грех уже не использовать mysqli, и забыть про инъекции с плейсхолдерами как страшный сон. Плюс экономия на времени парсинга запроса как приятный бонус)
в зенде допустим:
$db->query('UPDATE users SET login_time=? WHERE id=?', array($time, $id));
выше уже говорили про PDO. но к сожалению он включен не по дефолту, а MYSQLI использовать можно вполне. Имитация magic quotes напомнила мне, если честно:

//Далее не безопасный код, но только так можно исправить ситуацию со старой версией.
if ($_GET) {
    foreach ($_GET AS $key => $value) {
        $$key = $value; //Делаю все переменные GET простыми, как это было с reg_glob
    }
}
Ответ написан
zobov
@zobov Автор вопроса
понял, всем спасибо за советы! =)
Ответ написан
@edogs
По поводу самой идеи выше уже все всё сказали сказали… хотя если в скриптах есть тонна г-но кода, где программер не озабачивался прослэшиванием переменных, то такой способ может быть быстрым спасением, до тех пор пока код не приведут в порядок.
Единственное что добавим — такой способ убьет массивы, если что-то где-то передается как input name=«a[2]», то кирдык данным после «прослэшивания».
Ответ написан
Комментировать
Мой вариант:
//---------------- Процедура подключения к базе данных -----------------------//
function dbconnect() {
global $database;
if (!isset($database)) {
$database = mysql_connect("localhost", "**", "***");
mysql_select_db("xxx", $database);
}
}

//--------------------- Функция выполнения запросов --------------------------//
function sql_query($query) {
global $errors;
dbconnect();
$return = mysql_query($query);
$error = mysql_error();
if ($error=='') {
return $return;
}
else {
writelog('sql_error', date("y.m.d H:m:s")."\t".$error);
$errors .= $error;
return false;
};
}
//----------------------------------------------------------------------------//

//----------- Процедура проверки данных перед вставкой в запрос ---------------//
function checkfield($request) {
$request = trim($request);
if (isset($request)) {
// Если не число, то экранируем ковычки
if (is_numeric($request)) { return $request; }
else { dbconnect(); return mysql_real_escape_string($request); }
}
else { return ''; }
}
//----------------------------------------------------------------------------//
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы