Найдите уязвимость в этом PHP-фрагменте и предложите безопасную реализацию: $q = "SELECT * FROM users WHERE name = '".$_GET['name']."'"; $db->query($q)
Уязвимость: SQL-инъекция. Вставка пользовательского ввода напрямую в строку запроса позволяет злоумышленнику подставить часть SQL (например, name='\' OR \'1\'=\'1'), что приведёт к чтению/изменению данных.
Рекомендации и безопасная реализация: 1) Использовать подготовленные выражения (parameterized queries) и привязку параметров. 2) Установить правильную кодировку соединения (utf8mb4). 3) Применять принцип минимума прав для БД-пользователя и валидацию/ограничение входных данных по необходимости.
Примеры.
PDO (рекомендуется): $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $db->exec("SET NAMES utf8mb4"); stmt=stmt = stmt=db->prepare("SELECT * FROM users WHERE name = :name"); $stmt->execute([':name' => $_GET['name']]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
mysqli: $db->set_charset('utf8mb4'); stmt=stmt = stmt=db->prepare("SELECT * FROM users WHERE name = ?"); $stmt->bind_param('s', $_GET['name']); $stmt->execute(); result=result = result=stmt->get_result(); rows=rows = rows=result->fetch_all(MYSQLI_ASSOC);
(Менее предпочтительно) экранирование: name=name = name=db->real_escape_string(GET[′name′]);_GET['name']); GET[′name′]);q = "SELECT * FROM users WHERE name = '$name'"; — экранирование корректно только при надлежащей кодировке и не даёт преимуществ подготовленных выражений.
Коротко: замените конкатенацию строки запроса на подготовленные выражения с привязанными параметрами и настройте кодировку и права доступа.
Уязвимость: SQL-инъекция. Вставка пользовательского ввода напрямую в строку запроса позволяет злоумышленнику подставить часть SQL (например, name='\' OR \'1\'=\'1'), что приведёт к чтению/изменению данных.
Рекомендации и безопасная реализация:
1) Использовать подготовленные выражения (parameterized queries) и привязку параметров.
2) Установить правильную кодировку соединения (utf8mb4).
3) Применять принцип минимума прав для БД-пользователя и валидацию/ограничение входных данных по необходимости.
Примеры.
PDO (рекомендуется):
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->exec("SET NAMES utf8mb4");
stmt=stmt = stmt=db->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute([':name' => $_GET['name']]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
mysqli:
$db->set_charset('utf8mb4');
stmt=stmt = stmt=db->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param('s', $_GET['name']);
$stmt->execute();
result=result = result=stmt->get_result();
rows=rows = rows=result->fetch_all(MYSQLI_ASSOC);
(Менее предпочтительно) экранирование:
name=name = name=db->real_escape_string(GET[′name′]);_GET['name']);
G ET[′name′]);q = "SELECT * FROM users WHERE name = '$name'";
— экранирование корректно только при надлежащей кодировке и не даёт преимуществ подготовленных выражений.
Коротко: замените конкатенацию строки запроса на подготовленные выражения с привязанными параметрами и настройте кодировку и права доступа.