Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Принцип работы SQL-инъекции
SQL-инъекция — это уязвимость безопасности, возникающая из-за некорректной обработки пользовательского ввода, которая позволяет злоумышленнику вмешиваться в SQL-запросы приложения к базе данных.
Механизм атаки
Атака строится на внедрении произвольного SQL-кода в поля ввода приложения:
- Идентификация уязвимых мест — злоумышленник находит параметры, передаваемые в запрос (поля форм, URL-параметры).
- Внедрение специальных символов — использование кавычек, точек с запятой или SQL-команд для изменения логики запроса.
- Обход аутентификации — самый известный пример с входом в систему.
Рассмотрим классический пример:
-- Исходный запрос в коде приложения
SELECT * FROM users WHERE login = '[user_input]' AND password = '[user_input]';
Если пользователь введёт в поле логина:
admin' --
Запрос превратится в:
SELECT * FROM users WHERE login = 'admin' --' AND password = '[user_input]';
Комментарий -- отменяет проверку пароля!
Типы SQL-инъекций
1. In-band инъекции
Результат виден сразу в ответе приложения:
- Error-based — использование сообщений об ошибках СУБД для получения структуры БД
- Union-based — использование оператора UNION для объединения результатов
Пример UNION-атаки:
-- Определяем количество столбцов
' UNION SELECT NULL --
' UNION SELECT NULL, NULL --
-- Получаем данные
' UNION SELECT username, password FROM users --
2. Blind инъекции
Приложение не возвращает данные напрямую:
- Boolean-based — анализ логического поведения приложения
-- Проверка существования таблицы
' AND EXISTS(SELECT * FROM users) --
-- Поиск пароля посимвольно
' AND SUBSTRING(password, 1, 1) = 'a' --
- Time-based — использование задержек для определения истинности условий
-- Если первый символ пароля 'a', ждём 5 секунд
' AND IF(SUBSTRING(password, 1, 1) = 'a', SLEEP(5), 0) --
Последствия успешной атаки
- Чтение конфиденциальных данных (пароли, персональные данные)
- Изменение или удаление данных в базе
- Обход аутентификации и получение административных прав
- Выполнение команд ОС через возможности СУБД
Защита от SQL-инъекций в Go
1. Использование подготовленных выражений (Prepared Statements)
// ❌ Уязвимый код
query := fmt.Sprintf("SELECT * FROM users WHERE email = '%s'", userInput)
rows, err := db.Query(query)
// ✅ Безопасный код с подготовленным выражением
stmt, err := db.Prepare("SELECT * FROM users WHERE email = ?")
rows, err := stmt.Query(userInput)
2. Валидация и санация ввода
// Проверка допустимых символов
func isValidInput(input string) bool {
// Разрешаем только буквы, цифры и некоторые символы
re := regexp.MustCompile(`^[a-zA-Z0-9@._-]+$`)
return re.MatchString(input)
}
// Ограничение длины
if len(userInput) > 100 {
return errors.New("input too long")
}
3. Принцип минимальных привилегий
// Использование отдельного пользователя БД с ограниченными правами
dsn := "limited_user:password@/database?parseTime=true"
db, err := sql.Open("mysql", dsn)
4. ORM с параметризацией
// Использование GORM или подобных ORM
var users []User
db.Where("email = ?", userInput).Find(&users)
5. Web Application Firewall (WAF)
Дополнительный уровень защиты на уровне приложения или сети.
Лучшие практики защиты
- Всегда использовать параметризованные запросы — это основной и самый эффективный метод
- Никогда не доверять пользовательскому вводу — валидировать, фильтровать, экранировать
- Регулярно обновлять СУБД и драйверы — закрытие известных уязвимостей
- Логировать подозрительные запросы для своевременного обнаружения атак
- Проводить регулярное тестирование безопасности (ручное и автоматизированное)
SQL-инъекции остаются в топе уязвимостей OWASP уже много лет именно из-за неправильной обработки ввода разработчиками. В Go защита особенно важна, так как язык часто используется для высоконагруженных backend-сервисов, работающих с критичными данными.