Найдите уязвимость в PHP‑фрагменте: $username = $_GET['u']; $query = "SELECT * FROM users WHERE name = '$username'"; — опишите, как её эксплуатируют (SQL‑инъекция), практические последствия, способы защиты (подготовленные выражения, ORM, валидация, least privilege) и рекомендации по обучению студентов безопасной разработке
Уязвимость: в фрагменте $username = $_GET['u']; $query = "SELECT * FROM users WHERE name = '$username'"; — отсутствует разделение кода и данных (встроенная строка SQL), поэтому это классическая SQL‑инъекция. Как эксплуатируют (коротко и практично) - Если в GET-параметре u передать строку с кавычками и SQL, она попадёт прямо в запрос. Примеры полезных полезагрузок: - Получить всех пользователей: u=' OR '1'='1 Итоговый SQL: SELECT * FROM users WHERE name = '' OR '1'='1' - Аутентификация обходится (если запрос проверяет логин): u=admin' -- Итог: SELECT * FROM users WHERE name = 'admin' --' (комментарий обрывает остаток запроса) - Извлечение данных через UNION, слепые инъекции или получение схемы базы. - Возможны разные техники: error‑based, union‑based, boolean blind, time‑based blind, stacked queries (в зависимости от СУБД и настроек). Практические последствия - Чтение конфиденциальных данных (пароли, адреса, карты). - Модификация/удаление данных: UPDATE/DELETE/INSERT. - Аутентификация обходится — полный вход под чужим аккаунтом. - Выполнение произвольных команд на БД/сервере (если разрешены stacked queries). - Эскалация атаки: получение дампа, доступ к другим сервисам, RCE через уязвимости СУБД. - Потеря данных, репутационные и финансовые последствия, нарушения комплаенса. Способы защиты (конкретно и рекомендуемо) 1. Подготовленные выражения (parameterized queries) — основное: - Пример на PDO: $stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name"); $stmt->execute([':name' => $_GET['u']]); - Или mysqli: $stmt = $mysqli->prepare("SELECT * FROM users WHERE name = ?"); $stmt->bind_param('s', $_GET['u']); $stmt->execute(); 2. ORM/абстракция доступа к данным — современные ORM автоматически параметризуют запросы и уменьшают вероятность ошибок (Eloquent, Doctrine и т.д.). 3. Валидация и белые списки: - Сначала проверять формат/длину/символы (например, имя пользователя — только [A‑Z0‑9_], лимит длины). - Валидация не заменяет параметризацию, но снижает риск логических ошибок. 4. Экранирование — mysqli_real_escape_string только как последняя мера; плохо заменяет параметризацию. 5. Принцип минимальных привилегий (least privilege): - У БД‑пользователя приложения — только те права, которые необходимы (обычно SELECT/INSERT/UPDATE ограниченно). - Никогда не использовать административные учётки приложения. 6. Ограничение ошибок и логирование: - Не возвращать подробные ошибки SQL в ответе пользователю. - Логировать подозрительную активность и применять WAF/IPS при необходимости. 7. Дополнительно: подготовка параметров для LIMIT/OFFSET как integers через приведение/валидацию, использование хранимых процедур с параметрами. Рекомендации по обучению студентов безопасной разработке - Теория + практика: объяснять, что такое граница доверия входных данных и почему нужно разделять код и данные. - Лаборатории в изолированной среде: OWASP Juice Shop, DVWA, WebGoat — практические задания по SQLi и защите. - Код‑ревью и pair‑programming с фокусом на безопасность. - Включать тесты: unit/integ тесты и автоматические SAST/DAST инструменты в CI. - Учить безопасным API‑паттернам: parameterized queries, использование ORM, принципы least privilege. - Кейсы реальных инцидентов и постмортем‑разборы для понимания последствий. - Чеклисты безопасного кодирования и регулярные тренинги (включая OWASP Top 10). Краткий вывод: исправить код — заменить конкатенацию строки SQL на подготовленные выражения (PDO/mysqli/ORM), добавить валидацию входа, ограничить права БД и обеспечить логирование/мониторинг; обучать студентов через практические лаборатории и код‑ревью.
$username = $_GET['u'];
$query = "SELECT * FROM users WHERE name = '$username'";
— отсутствует разделение кода и данных (встроенная строка SQL), поэтому это классическая SQL‑инъекция.
Как эксплуатируют (коротко и практично)
- Если в GET-параметре u передать строку с кавычками и SQL, она попадёт прямо в запрос. Примеры полезных полезагрузок:
- Получить всех пользователей: u=' OR '1'='1
Итоговый SQL: SELECT * FROM users WHERE name = '' OR '1'='1'
- Аутентификация обходится (если запрос проверяет логин): u=admin' --
Итог: SELECT * FROM users WHERE name = 'admin' --'
(комментарий обрывает остаток запроса)
- Извлечение данных через UNION, слепые инъекции или получение схемы базы.
- Возможны разные техники: error‑based, union‑based, boolean blind, time‑based blind, stacked queries (в зависимости от СУБД и настроек).
Практические последствия
- Чтение конфиденциальных данных (пароли, адреса, карты).
- Модификация/удаление данных: UPDATE/DELETE/INSERT.
- Аутентификация обходится — полный вход под чужим аккаунтом.
- Выполнение произвольных команд на БД/сервере (если разрешены stacked queries).
- Эскалация атаки: получение дампа, доступ к другим сервисам, RCE через уязвимости СУБД.
- Потеря данных, репутационные и финансовые последствия, нарушения комплаенса.
Способы защиты (конкретно и рекомендуемо)
1. Подготовленные выражения (parameterized queries) — основное:
- Пример на PDO:
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute([':name' => $_GET['u']]);
- Или mysqli:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param('s', $_GET['u']);
$stmt->execute();
2. ORM/абстракция доступа к данным — современные ORM автоматически параметризуют запросы и уменьшают вероятность ошибок (Eloquent, Doctrine и т.д.).
3. Валидация и белые списки:
- Сначала проверять формат/длину/символы (например, имя пользователя — только [A‑Z0‑9_], лимит длины).
- Валидация не заменяет параметризацию, но снижает риск логических ошибок.
4. Экранирование — mysqli_real_escape_string только как последняя мера; плохо заменяет параметризацию.
5. Принцип минимальных привилегий (least privilege):
- У БД‑пользователя приложения — только те права, которые необходимы (обычно SELECT/INSERT/UPDATE ограниченно).
- Никогда не использовать административные учётки приложения.
6. Ограничение ошибок и логирование:
- Не возвращать подробные ошибки SQL в ответе пользователю.
- Логировать подозрительную активность и применять WAF/IPS при необходимости.
7. Дополнительно: подготовка параметров для LIMIT/OFFSET как integers через приведение/валидацию, использование хранимых процедур с параметрами.
Рекомендации по обучению студентов безопасной разработке
- Теория + практика: объяснять, что такое граница доверия входных данных и почему нужно разделять код и данные.
- Лаборатории в изолированной среде: OWASP Juice Shop, DVWA, WebGoat — практические задания по SQLi и защите.
- Код‑ревью и pair‑programming с фокусом на безопасность.
- Включать тесты: unit/integ тесты и автоматические SAST/DAST инструменты в CI.
- Учить безопасным API‑паттернам: parameterized queries, использование ORM, принципы least privilege.
- Кейсы реальных инцидентов и постмортем‑разборы для понимания последствий.
- Чеклисты безопасного кодирования и регулярные тренинги (включая OWASP Top 10).
Краткий вывод: исправить код — заменить конкатенацию строки SQL на подготовленные выражения (PDO/mysqli/ORM), добавить валидацию входа, ограничить права БД и обеспечить логирование/мониторинг; обучать студентов через практические лаборатории и код‑ревью.