#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 місяця
Також варто подивитися