SQL Injection
Вредоносный SQL код вставляется в запрос, чтобы выполнить любые команды базы данных, на которые у пользователя есть привелегии.
Например, в запросе SELECT * FROM users WHERE username=’$user’ злоумышленник может передать ' или "=' для поля $user, чтобы увидеть все данные в таблице users.
Такое поведение можно предотвратить, используя prepared statements или специфичные для базы функции экранирование, такие как например mysqli_real_escape_string().
Например, есть форма логина:
<form method="login.php" action="POST">
Username: <input type="text" name="username" />
<br />
Password: <input type="password" name="password" />
<br />
<input type="submit" value="Log In" />»
</form>
и код, который выполняет вход на основе данных из этой формы:
$username = $_POST['username'];
$password = password_hash(
$_POST['password'], PASSWORD_DEFAULT
);
$sql = "SELECT *
FROM users
WHERE username = '{$username}' AND
password = '{$password}'";
/* database connection and query code */
if (count($results) > 0) {
// Successful login attempt
}
В данном примере нет фильтрации входных данных из POST. Вместо этого сырые введенные данные вставляются в переменную $username. Затем этот ввод используется в SQL-выражении. Злоумышленник может попытаться залогиниться, используя такой логин:
username' OR 1 = 1 --
С этим логином и пустым паролем SQL-выражение теперь имеет вид:
SELECT *
FROM users
WHERE
username = 'username' OR 1 = 1 --' AND
password =
А так как 1=1 всегда будет TRUE а строка -- начинает комментарии в SQL-выражении, то все после них будет проигнорировано и в результате будут успешно возвращены все записи из таблицы.
Подобного рода атаки становятся возможными из-за отсутствия фильтрации и экранирования входных данных. Чтобы обезопасить себя следует использовать prepared statements в своем приложении или экранировать данные.