76 lines
5.2 KiB
Markdown
76 lines
5.2 KiB
Markdown
---
|
||
title: SQL Injection
|
||
localeTitle: SQL-инъекция
|
||
---
|
||
## SQL-инъекция
|
||
|
||
Уязвимость в приложении, вызванная тем, что программист не дезинфицирует ввод, прежде чем включать его в запрос в базу данных. Это приводит к тому, что злоумышленник имеет полное чтение и чаще всего не пишет доступ к базе данных. При таком типе доступа злоумышленник может делать очень плохие вещи.
|
||
|
||
### Пример атаки SQL Injection
|
||
|
||
В приведенном ниже PHP-скрипте выполняется SQL-запрос для получения электронной почты пользователя по идентификатору. Однако вход не подвергается дезинфекции, что делает его уязвимым для SQL Injection
|
||
|
||
```PHP
|
||
<?php
|
||
$input = $_GET['id'];
|
||
$dbserver = "localhost";
|
||
$dbuser = "camper";
|
||
$dbpass = "supersecretcampsitepassword";
|
||
$dbname = "freecodecamp";
|
||
|
||
$conn = new mysqli($dbserver, $dbuser, $dbpass, $dbname);
|
||
|
||
if ($conn->connect_error) {
|
||
die("Connection failed: " . $conn->connect_error);
|
||
}
|
||
|
||
$sql = "SELECT email FROM users WHERE id =" . $input;
|
||
|
||
$result = $conn->query($sql);
|
||
|
||
if ($result->num_rows > 0) {
|
||
while($row = $result->fetch_assoc()) {
|
||
echo $row["email"];
|
||
}
|
||
} else {
|
||
echo "no results";
|
||
}
|
||
|
||
$conn->close();
|
||
```
|
||
|
||
```SQL
|
||
SELECT email FROM users WHERE id = `$input`;
|
||
```
|
||
|
||
Таким образом, с вышесказанным вход не вводится в тип (т.е., вводя вход с (int), так что допускается только число) и не экранируется, позволяя кому-либо выполнять атаку SQL Injection - например, URL `getemailbyuserid.php?id=1'; My Query Here-- -` позволит вам запускать произвольные SQL-запросы без особых усилий.
|
||
|
||
### Защита вашего сайта от SQL-инъекций в PHP
|
||
|
||
Существует несколько подходов к защите вашего сайта от SQL Injection Attacks. Этими подходами являются «Белый список», «Литье по типу» и «Экранирование символов»
|
||
|
||
**Whitelisting:** Белый список используется в тех случаях, когда ожидаются только несколько входов. Вы можете перечислить каждый ожидаемый ввод в PHP Switch, а затем по умолчанию использовать недопустимый ввод. Вам не нужно беспокоиться о проблеме с литьем типа или обхода escape-кода персонажа, но разрешенный вход ограниченно ограничен. Он остается вариантом, см. Пример ниже.
|
||
|
||
```PHP
|
||
<?php
|
||
switch ($input) {
|
||
case "1":
|
||
//db query 1
|
||
break;
|
||
case "2":
|
||
//db query 2
|
||
break;
|
||
default:
|
||
// invalid input return error
|
||
}
|
||
```
|
||
|
||
**Тип Литье:** Подход типа литья обычно используется для приложения с использованием числового ввода. Просто введите вход с `(int) $input` и допустимо только числовое значение.
|
||
|
||
**Экранирование символов:** Подход к экранированию персонажа будет избегать символов, таких как кавычки и косые черты, предоставленные пользователем для предотвращения атаки. Если вы используете MySQL Server и библиотеку MySQLi для доступа к своей базе данных, `mysqli_real_escape_string($conn, $string)` будет принимать два аргумента, соединение MySQLi и строку и будет надлежащим образом удалять вход пользователя для блокировки атаки на SQL-инъекцию , Точная функция, которую вы используете, зависит от типа базы данных и библиотеки php, которую вы используете, чтобы проверить документацию библиотеки php для получения дополнительной информации об экранировании ввода пользователя.
|
||
|
||
#### Дополнительная информация:
|
||
|
||
* [OWASP Wiki - SQL-инъекция](https://www.owasp.org/index.php/SQL_Injection)
|
||
* [Справочник по инъекции php.net SQL](https://secure.php.net/manual/en/security.database.sql-injection.php)
|
||
* [Справочник по MySQL True Real Escape String](https://secure.php.net/manual/en/mysqli.real-escape-string.php) |