SDA
11.08.2005, 14:17
SQL-инъекция — это возможность пользователя неправомерно выполнять SQL-запросы на сервере. От этого определения, собственно, и нужно танцевать. Чтобы хакер не передал на сервер свой SQL-запрос, надо лишить его такой возможности, залатав все дыры. Рассмотрим небольшой пример.
Многие сайты имеют систему авторизации пользователя на сервере. Как правило, она реализована крайне просто: специальный скрипт сверяет введенные юзером логин/пароль с данными из базы, после чего выдает соответствующий результат. На практике это выглядит примерно так:
$valid = mysql_query("SELECT Username, Password FROM Users WHERE Username = ' ".$_POST['username']." ' and Password = ' ".$_POST['password']." ' ");
С первого взгляда вполне безопасный код, но… Стоит ввести в поле имени пользователя «' OR 1=1 #» (без кавычек), и серверу передастся следующий запрос:
SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''
Хэш-символ (#) в SQL-запросах используется как указатель на комментарии, а все, что идет после него (все необходимые условия для выполнения запроса), сервером попросту игнорируется. Единица всегда равна единице (1=1), поэтому логическое условие OR 1=1 не накладывает ограничения на результат запроса. В итоге сервер, имея на то полные основания, вернет в качестве результата таблицу со всеми логинами и паролями. Как тебе?
Чтобы избавиться от бага, в нашем случае достаточно проверять введенную пользователем информацию на наличие кавычек. Не будет кавычек — не будет изменено условие запроса, а значит, не будет и инъекции. Для этого воспользуемся следующей функцией, которая добавляет перед кавычкой слэш и превращает его в управляющую последовательность: \'. Она не изменит запрос, а просто станет частью условия наравне со всеми остальными символами.
function safe_term($variable) {
$variable = addslashes(trim($variable));
return $variable;
}
А теперь с ее помощью изменим наш запрос:
$username = safe_term($_POST['username']);
$password = safe_term($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = ' ".$username." ' and Password = ' ".$password." ' ");
Многие сайты имеют систему авторизации пользователя на сервере. Как правило, она реализована крайне просто: специальный скрипт сверяет введенные юзером логин/пароль с данными из базы, после чего выдает соответствующий результат. На практике это выглядит примерно так:
$valid = mysql_query("SELECT Username, Password FROM Users WHERE Username = ' ".$_POST['username']." ' and Password = ' ".$_POST['password']." ' ");
С первого взгляда вполне безопасный код, но… Стоит ввести в поле имени пользователя «' OR 1=1 #» (без кавычек), и серверу передастся следующий запрос:
SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''
Хэш-символ (#) в SQL-запросах используется как указатель на комментарии, а все, что идет после него (все необходимые условия для выполнения запроса), сервером попросту игнорируется. Единица всегда равна единице (1=1), поэтому логическое условие OR 1=1 не накладывает ограничения на результат запроса. В итоге сервер, имея на то полные основания, вернет в качестве результата таблицу со всеми логинами и паролями. Как тебе?
Чтобы избавиться от бага, в нашем случае достаточно проверять введенную пользователем информацию на наличие кавычек. Не будет кавычек — не будет изменено условие запроса, а значит, не будет и инъекции. Для этого воспользуемся следующей функцией, которая добавляет перед кавычкой слэш и превращает его в управляющую последовательность: \'. Она не изменит запрос, а просто станет частью условия наравне со всеми остальными символами.
function safe_term($variable) {
$variable = addslashes(trim($variable));
return $variable;
}
А теперь с ее помощью изменим наш запрос:
$username = safe_term($_POST['username']);
$password = safe_term($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = ' ".$username." ' and Password = ' ".$password." ' ");