Разберите фрагмент SQL-кода в веб-приложении: query = "SELECT * FROM users WHERE name = '" + name + "'"; — объясните уязвимость и предложите безопасные альтернативы
Уязвимость: это классический SQL‑инъекшн. При конкатенации строки запроса с внешним вводом (переменная `name`) атакующий может подставить фрагмент SQL, изменить логику запроса или выполнить произвольные команды в БД. Пример атаки - Ввод злоумышленника: `name = "' OR '111' = '111'"` - Получаемый запрос: `"SELECT * FROM users WHERE name = '' OR '1' = '1'"` — условие всегда истинно, возвращаются все строки или выполняется нежелательное действие. Последствия: утечка данных, обход аутентификации, изменение/удаление данных, получение доступа к ОС через расширения БД. Безопасные альтернативы (коротко, с примерами) - Параметризованные запросы / подготовленные выражения (recommended) - Python (psycopg2): cursor.execute("SELECT * FROM users WHERE name = %s", (name,)) - PHP (PDO): $stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name"); $stmt->execute(['name' => $name]); - Java: PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name = ?"); ps.setString(1, name); - Node (pg): client.query('SELECT * FROM users WHERE name = $1', [name]); - ORM / query builders: используйте встроенные механизмы (SQLAlchemy, Hibernate, Entity Framework и т.д.), они автоматически параметризуют запросы. - Белый список / валидация: для полей с ограниченным форматом (имена, id) применяйте валидацию по регулярным выражениям или списку допустимых значений. - Экранирование как запасной вариант: используйте штатные функции драйвера для экранирования, но не полагайтесь на это вместо параметризации. - Ограничения доступа: учётная запись БД для приложения должна иметь минимальные права; логирование и мониторинг запросов. Короткий чек‑лист по исправлению - Заменить конкатенацию на параметризацию. - Провести валидацию/ограничение длины вводимых данных. - Применить принцип наименьших привилегий для БД‑пользователя. - Добавить логирование и тесты на SQL‑инъекции (fuzzing). Итог: не конкатенируйте пользовательский ввод в SQL — используйте подготовленные выражения/параметры или ORM и дополнительно валидацию и минимальные привилегии.
Пример атаки
- Ввод злоумышленника: `name = "' OR '111' = '111'"`
- Получаемый запрос: `"SELECT * FROM users WHERE name = '' OR '1' = '1'"` — условие всегда истинно, возвращаются все строки или выполняется нежелательное действие.
Последствия: утечка данных, обход аутентификации, изменение/удаление данных, получение доступа к ОС через расширения БД.
Безопасные альтернативы (коротко, с примерами)
- Параметризованные запросы / подготовленные выражения (recommended)
- Python (psycopg2):
cursor.execute("SELECT * FROM users WHERE name = %s", (name,))
- PHP (PDO):
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute(['name' => $name]);
- Java:
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name = ?");
ps.setString(1, name);
- Node (pg):
client.query('SELECT * FROM users WHERE name = $1', [name]);
- ORM / query builders: используйте встроенные механизмы (SQLAlchemy, Hibernate, Entity Framework и т.д.), они автоматически параметризуют запросы.
- Белый список / валидация: для полей с ограниченным форматом (имена, id) применяйте валидацию по регулярным выражениям или списку допустимых значений.
- Экранирование как запасной вариант: используйте штатные функции драйвера для экранирования, но не полагайтесь на это вместо параметризации.
- Ограничения доступа: учётная запись БД для приложения должна иметь минимальные права; логирование и мониторинг запросов.
Короткий чек‑лист по исправлению
- Заменить конкатенацию на параметризацию.
- Провести валидацию/ограничение длины вводимых данных.
- Применить принцип наименьших привилегий для БД‑пользователя.
- Добавить логирование и тесты на SQL‑инъекции (fuzzing).
Итог: не конкатенируйте пользовательский ввод в SQL — используйте подготовленные выражения/параметры или ORM и дополнительно валидацию и минимальные привилегии.