PHP. Предотвращение SQL инъекций


Применение mysql_real_escape_string() к каждой переменной, вставляемой в запрос, предотвращает SQL Injection. Нижеследующий код является одним из вариантом составления запросов и не зависит от установки Magic Quotes.


<?php
// Функция экранирования переменных

function
quote_smart($value)
{

    // если magic_quotes_gpc отключена - используем stripslashes
    if (get_magic_quotes_gpc()) {
        $value = stripslashes($value);
    }
    // Если переменная - число, то экранировать её не нужно
    // если нет - то окружем её кавычками, и экранируем
    if (!is_numeric($value)) {
        $value = "'" . mysql_real_escape_string($value) . "'";
    }
    return $value;
}


// Подключаемся

$link
= mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
    OR die(mysql_error());

// Составляем безопасный запрос

$query
= sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
            quote_smart($_POST['username']),
            quote_smart($_POST['password']));

mysql_query
($query);
?>

Запрос, составленный таким образом, будет выполнен без ошибок, и взлом с помощью SQL Injection окажется невозможен.

Со временем в документации вычитал, что данный метод - mysql_real_escape_string - считается устаревшим и взамен предлагается использовать:

- mysqli_real_escape_string()
- PDO::quote()

Пример простой обработки значений, которые пришли от пользователя. Для этого можно использовать функции strip_tags() и substr() для удаления всех тегов HTML и сокращения его размера. Такая обработка никогда не помешает — нельзя целиком доверять тому, что вводит пользователь.
При очистке значения выполним один дополнительный шаг в виде процедуры mysql_escape_string(), которая удалит все прочие глюки (такие как одинарные знаки кавычек), которые могут поставить базу данных в тупик :)

$term = strip_tags( substr( $_POST['search'], 0, 100 ) );
$term = mysql_escape_string( $term );

Также можно пользоваться дополнительными проверками на тип введенных пользователем данных, например - is_numeric(). Тогда, если на входе не числовое значение, то применяем очистку выше описанным способом. Всем доброго времени суток :)