Поясните риск и предложите реализацию с подготовленными выражениями

18 Ноя в 10:11
4 +4
0
Ответы
1
Риск (кратко)
- SQL‑инъекция: при конкатенации пользовательских данных в SQL строка запроса может быть изменена атакующим, что ведёт к утечке/изменению/удалению данных или обходу аутентификации (примеры типа 1=1 \;1=1\;1=1).
- Факторы риска: прямое склеивание строк запроса, недостаточная валидация, избыточные привилегии БД, динамическое подставление имен таблиц/столбцов без белого списка.
Основная защита
- Использовать подготовленные выражения (prepared statements / parameterized queries) с привязкой параметров.
- Валидировать / белить вход для частей SQL, которые нельзя параметризовать (identifiers, ORDER BY).
- Минимизировать привилегии учётных записей БД.
- Логировать и мониторить аномалии.
Реализации (коротко, уязвимый → безопасный)
1) PHP PDO
Уязвимо:
```
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = $id";
$db->query($sql);
```
Безопасно:
```
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute([':id' => $id]);
$row = $stmt->fetch();
```
2) Python (psycopg2, PostgreSQL)
Уязвимо:
```
cur.execute("SELECT * FROM users WHERE login = '%s'" % login)
```
Безопасно:
```
cur.execute("SELECT * FROM users WHERE login = %s", (login,))
row = cur.fetchone()
```
3) Python (sqlite3)
Безопасно:
```
cur.execute("SELECT * FROM items WHERE price <= ?", (max_price,))
```
4) Node.js (mysql2 / mysql)
Уязвимо:
```
conn.query("SELECT * FROM users WHERE name = '" + name + "'");
```
Безопасно:
```
conn.execute("SELECT * FROM users WHERE name = ?", [name])
```
5) Java (JDBC)
Безопасно:
```
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE email = ?");
ps.setString(1, email);
ResultSet rs = ps.executeQuery();
```
6) C# (SqlClient)
Безопасно:
```
using (var cmd = new SqlCommand("SELECT * FROM Users WHERE Id = @id", conn)) {
cmd.Parameters.AddWithValue("@id", id);
var rdr = cmd.ExecuteReader();
}
```
Замечания и лучшие практики
- Prepared statements не параметризуют имена таблиц/столбцов и SQL‑фрагменты. Для них используйте белые списки и валидацию.
- Для числовых лимитов/offset лучше явно приводить к целому: пример default лимита 10\;1010 — `limit = int(request.args.get('limit', 10))`.
- Не доверяйте проверкам на клиенте; валидируйте на сервере.
- Привилегии БД должны быть минимальными: приложение — только SELECT/INSERT/UPDATE/DELETE по необходимости.
Если нужно, могу прислать пример для конкретного языка/БД или показать защиту для динамических идентификаторов (таблицы/ORDER BY).
18 Ноя в 10:20
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир