#2 – Что такое SQL Injection и как их находить?
Видеоурок
Что такое SQL Injection?
На самом деле, это как раз та самая дыра, из-за которой утекали данные из крупных банков, государственных порталов, медицинских систем и даже сайтов NASA. Проблема легко устраняется, но до сих пор входит в ТОП-10 наиболее частых и опасных уязвимостей во всех типах приложений.
SQL-инъекция — это атака, при которой злоумышленник вставляет SQL-код прямо внутрь вашего запроса к базе данных. То есть, если ваш код работает с базой через строку, куда вставляются данные от пользователя, то при неправильной обработке этот пользователь может внедрить не просто имя или логин, а целый SQL-запрос.
Если это произойдёт, он может: просматривать содержимое таблиц, удалять данные, менять чужие пароли или даже получить доступ к административной части сайта.
Реальный пример
Рассмотрим пример на языке Python с использованием базы данных SQLite. Эти технологии выбраны только в качестве примера — на практике такая уязвимость возможна с любым языком программирования, работающим с базами данных и пользовательским вводом.
Допустим, у нас есть простой скрипт авторизации. Вот его код:
login = input("Enter your username: ")
query = f"SELECT * FROM users WHERE username = '{login}'"
cursor.execute(query)На первый взгляд — обычный код. Вводим логин, выполняется запрос в базу, и нам возвращается пользователь. Всё работает.
И всё действительно будет работать — пока пользователи добросовестны. Но теперь допустим, что злоумышленник вводит вместо логина текст: ' OR 1=1 --
В итоге SQL-запрос будет выглядеть так:
SELECT * FROM users WHERE username = '' OR 1=1 --'Что это значит? Это значит: "выбрать всех пользователей, потому что условие 1=1 всегда истинно". А два прочерка в конце — это комментарий, отключающий оставшуюся часть запроса.
В результате возвращается вся таблица пользователей.
Более того, если ваш код устроен так, что при нахождении хотя бы одного пользователя вы сразу предоставляете доступ — злоумышленник получит вход в систему.
Чем опасны SQLi?
SQL-инъекция — это не просто «небольшой баг». Это прямая угроза утечки данных. А в некоторых случаях — удаления всей базы данных, изменения информации или получения root-доступа к серверу.
И это не преувеличение. Существуют тысячи случаев, когда через публичные формы входа хакеры получали миллионы логинов и паролей. SQL-инъекция также использовалась для обхода авторизации и проникновения в админ-панели. Иногда через неё можно даже выполнить команды операционной системы.
Поэтому защита от SQL-инъекций — абсолютно необходима.
Пишем небезопасный код
Вот пример уязвимого кода на Python с использованием SQLite. Мы получаем данные от пользователя и напрямую подставляем их в SQL-команду. Затем с помощью cursor.fetchone() получаем первую найденную запись из базы данных.
Если запись есть — пользователь существует, и мы разрешаем доступ. В противном случае — доступ запрещён.
import sqlite3
conn = sqlite3.connect("users.db")
cursor = conn.cursor()
username = input("Введите логин: ")
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)
result = cursor.fetchone()
if result:
print("Вход разрешен!")
else:
print("Пользователя не найдено.")Запустите программу и введите в поле логина следующее: ' OR '1'='1. Вы получите доступ, даже не указав настоящего пользователя. Это классический пример SQL-инъекции.
Добавление безопасности
В разных языках программирования защита реализуется по-разному, но главное правило: никогда не вставляйте пользовательские данные напрямую в SQL-запрос. Вместо этого используйте параметризованные запросы.
В Python это будет выглядеть так:
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))Здесь сначала указывается шаблон SQL-команды, а затем через запятую передаются параметры. Это полностью исключает SQL-инъекцию, так как переданные данные обрабатываются как текст, а не как часть SQL-запроса.
В других языках подстановка параметров может отличаться, но суть всегда одна: не вставляйте данные напрямую — используйте параметризованные запросы.
Как найти SQLi через sqlmap?
Существует мощный инструмент — sqlmap. Это программа, которая автоматически тестирует параметры URL, формы и другие точки взаимодействия на предмет возможности внедрения SQL-кода.
Пример использования sqlmap через терминал:
sqlmap -u "http://localhost/login.php?login=test" --dbsЭтот запрос отправит серию инъекций на указанный адрес. Если сервер уязвим, sqlmap покажет список доступных баз данных.
Таким образом можно быстро проверить проект на уязвимости и оперативно их устранить.
ORM — дополнительное решение
Ещё один способ защититься — использовать ORM (Object-Relational Mapping). Это библиотеки, которые позволяют работать с базой данных через объекты и модели, а не напрямую через SQL. Они автоматически экранируют вводимые данные и защищают от большинства атак.
Примеры ORM в разных языках:
- — SQLAlchemy
- — Eloquent
- — Prisma
Если вы используете ORM и правильно его конфигурируете — риск SQL-инъекций значительно снижается.
Исходный код
Весь код будет доступен после подписки на проект! Задание к уроку
Необходимо оформить подписку на проект, чтобы получить доступ ко всем домашним заданиям
Большое задание по курсу
Вам необходимо оформить подписку на сайте, чтобы иметь доступ ко всем большим заданиям. В задание входит методика решения, а также готовый проект с ответом к заданию.
PS: подобные задания доступны при подписке от 1 месяца
Также стоит посмотреть