Дан SQL-запрос в веб-приложении: "SELECT * FROM users WHERE login = '" + login + "' AND pass = '" + pass + "';" — опишите все виды атак, которые допустим этот код, как их можно реализовать, и перечислите несколько безопасных способов переписать и защитить такую аутентификацию
Код "SELECT * FROM users WHERE login = '" + login + "' AND pass = '" + pass + "';" имеет сразу несколько серьёзных проблем безопасности и делает приложение уязвимым для множества атак. Ниже — обзор того, какие категории атак он допускает впонятном,нонеэксплуатативномвидев понятном, но не эксплуатативном видевпонятном,нонеэксплуатативномвиде, какие последствия это даёт, а также практические безопасные способы переписать аутентификацию.
1) Что конкретно опасно в этом коде
Конкатенация пользовательского ввода в SQL — классическая уязвимость SQL-инъекции.Вероятно, пароли хранятся в БД в открытом виде посколькусравниваютполеpassнапрямуюпоскольку сравнивают поле pass напрямуюпосколькусравниваютполеpassнапрямую — это критично.SELECT * — может возвращать больше данных, чем требуется.Скорее всего, отсутствуют: проверка/ограничение ошибок, ограничение прав БД-пользователя, защита от брутфорса.
2) Типы атак, которые допускает такой код высокоуровнево,безпошаговыхэксплойтоввысокоуровнево, без пошаговых эксплойтоввысокоуровнево,безпошаговыхэксплойтов
SQL-инъекция вцеломв целомвцелом. Позволяет манипулировать SQL-запросом, изменить логику WHERE, прочитать/изменить/удалить данные, выполнять нежелательные запросы. Подвиды SQL-инъекции:Тавтологические/авторизационные обходы: злоумышленник может изменить условие так, чтобы оно всегда было истинно чтопозволяетобходитьаутентификациючто позволяет обходить аутентификациючтопозволяетобходитьаутентификацию.Выборочные UNION−подобныеUNION-подобныеUNION−подобные и ошибка-ориентированные инъекции: используются для вытаскивания данных из других таблиц.Слепая boolean−based/time−basedboolean-based / time-basedboolean−based/time−based инъекция: когда сервер не выдаёт прямой результат, атакующий получает информацию побитово по ответам сервера/времени ответа.Множественные/стековые запросы еслиСУБД/драйверразрешаютесли СУБД/драйвер разрешаютеслиСУБД/драйверразрешают — позволяют выполнить несколько операторов.Перехват и брутфорс паролей Если пароли хранятся в открытом виде, компрометация БД = компрометация всех паролей.Отсутствие ограничений на число попыток позволяет брутфорс и credential stuffing.Информационное раскрытие / разведка Ошибки SQL и подробные сообщения могут раскрывать схему БД, имена таблиц/полей, признаки используемой СУБД.Вторичные уязвимости Если полученные из БД данные потом выводятся в HTML без экранирования — возможен XSS.Если входные данные используются в shell-командах или LDAP/OS-командах — возможны другие инъекции.Тайминговые/криптографические атаки Если сравнение паролей выполняется небезопасно не−константноевремяне-константное времяне−константноевремя, возможны утечки информации через тайминговые атаки.
3) Влияние / последствия успешной атаки
Полный компромисс БД: чтение всех пользователей и паролей, персональных данных и т. п.Аутентификация обходится — злоумышленник получает доступ к аккаунтам.Модификация данных, создание/удаление записей.Утечка резервных данных и последующие массовые взломы еслипаролинехешированыесли пароли не хешированыеслипаролинехешированы.Возможный RCE/эскалация привилегий взависимостиотокруженияв зависимости от окружениявзависимостиотокружения.
4) Как защищать — общие принципы
Никогда не конкатенировать пользовательский ввод в SQL.Хранить пароли только в виде криптографически безопасных хэшей Argon2id/bcrypt/scryptArgon2id / bcrypt / scryptArgon2id/bcrypt/scrypt, с уникальной солью для каждой записи.Использовать параметризованные запросы preparedstatementsprepared statementspreparedstatements или ORM с безопасной привязкой параметров.Минимизировать привилегии учётной записи БД, которую использует приложение толькоSELECT/UPDATE/INSERTдлянужныхтаблицтолько SELECT/UPDATE/INSERT для нужных таблицтолькоSELECT/UPDATE/INSERTдлянужныхтаблиц.Ограничивать выдачу подробных SQL-ошибок пользователю — логировать их на сервер.Вводить защиту от брутфорса: rate limiting, задержки, блокировка аккаунта, CAPTCHA.Использовать HTTPS, HSTS, безопасные cookie HttpOnly,Secure,SameSiteHttpOnly, Secure, SameSiteHttpOnly,Secure,SameSite, и многофакторную аутентификацию MFAMFAMFA.Включить мониторинг, WAF и аудит запросов/логов.Проводить проверку и тестирование на уязвимости SAST/DAST/пентестSAST/DAST/пентестSAST/DAST/пентест.
5) Практические безопасные варианты реализации аутентификации Ниже — безопасная логика в общем виде:
На этапе регистрации: хешировать пароль безопасным алгоритмом и сохранять только хэш и соль еслиалгоритмтребуетесли алгоритм требуетеслиалгоритмтребует, НЕ хранить plain.На этапе логина: Получить запись пользователя по логину параметризованныйзапроспараметризованный запроспараметризованныйзапрос.Если запись есть — проверить введённый пароль с сохранённым хэшем с помощью безопасной функции верификации котораяделаетвнутреннийсоль/итерациикоторая делает внутренний соль/итерациикотораяделаетвнутреннийсоль/итерации.Выполнить проверку учёта блокировок/locked/disabled и, при успехе, создать сессию/токен.
Подготовленный запрос: SELECT id, password_hash FROM users WHERE login = :loginЗатем password_verify($pass, $row['password_hash'])Библиотека password_hash поддерживает bcrypt / Argon2 на современных PHP.
Python psycopg2psycopg2psycopg2 + argon2:
cursor.execute("SELECT id, password_hash FROM users WHERE login = %s", (login,))Использовать библиотеку argon2-cffi для сравнения: argon2.PasswordHasher.verifyhash,passwordhash, passwordhash,password
Java JDBCJDBCJDBC + PreparedStatement:
PreparedStatement stmt = conn.prepareStatement("SELECT id, password_hash FROM users WHERE login = ?");stmt.setString1,login1, login1,login;Результат -> проверка хеша с библиотекой BCrypt/Argon2.
client.query('SELECT id, password_hash FROM users WHERE login = $1', [login])await argon2.verifyhash,passwordhash, passwordhash,password
вкаждомпримереважныподготовленныезапросыиотдельнаяпроверкахешанасервере—никогданевключайтепарольвSQLдлясравненияв каждом примере важны подготовленные запросы и отдельная проверка хеша на сервере — никогда не включайте пароль в SQL для сравнениявкаждомпримереважныподготовленныезапросыиотдельнаяпроверкахешанасервере—никогданевключайтепарольвSQLдлясравнения
6) Дополнительные меры и хорошие практики
Не показывайте детальные ошибки аутентификации «internalerror»,«SQLerror»«internal error», «SQL error»«internalerror»,«SQLerror». Для пользователя — общие сообщения «неверныеучётныеданные»«неверные учётные данные»«неверныеучётныеданные».Логируйте подозрительную активность и включите алерты.Применяйте принцип наименьших привилегий для БД-пользователя нетправDROP/SHOW/CREATE,еслиненужнынет прав DROP/SHOW/CREATE, если не нужнынетправDROP/SHOW/CREATE,еслиненужны.Отключите возможность выполнения нескольких SQL-операторов одним запросом, если драйвер/СУБД позволяет.Внедрите MFA и защищённые сессионные токены JWTскороткимсрокомилисерверныесессииJWT с коротким сроком или серверные сессииJWTскороткимсрокомилисерверныесессии.Регулярно обновляйте зависимости, СУБД и используемые библиотеки хеширования.Рассмотрите использование специализированных провайдеров аутентификации OAuth/OpenIDConnect,внешниеIdentity−платформыOAuth/OpenID Connect, внешние Identity-платформыOAuth/OpenIDConnect,внешниеIdentity−платформы при необходимости.
7) Заключение — конкретные шаги, которые нужно выполнить прямо сейчас
Перейти на параметризованные запросы preparedstatementsprepared statementspreparedstatements для любых SQL-запросов с вводом пользователей.Пересмотреть хранение паролей — если пароли в БД не хешированы, срочно потребовать смены пароля и заменить хранение на Argon2/bcrypt.Отключить показ SQL-ошибок пользователям; добавить логирование.Ввести защиту от брутфорса rate−limiting,блокировки,CAPTCHArate-limiting, блокировки, CAPTCHArate−limiting,блокировки,CAPTCHA и MFA.Провести аудит привилегий БД и ограничить права приложения.Выполнить тестирование безопасности сканирование/пентестсканирование/пентестсканирование/пентест.
Если хотите, могу:
Показать конкретные безопасные примеры кода для языка/стека, который вы используете (PHP/Java/Python/Node/C#).Сформулировать чек-лист по исправлению уязвимости и по hardening-аутентификации.
Код
"SELECT * FROM users WHERE login = '" + login + "' AND pass = '" + pass + "';"
имеет сразу несколько серьёзных проблем безопасности и делает приложение уязвимым для множества атак. Ниже — обзор того, какие категории атак он допускает впонятном,нонеэксплуатативномвидев понятном, но не эксплуатативном видевпонятном,нонеэксплуатативномвиде, какие последствия это даёт, а также практические безопасные способы переписать аутентификацию.
1) Что конкретно опасно в этом коде
Конкатенация пользовательского ввода в SQL — классическая уязвимость SQL-инъекции.Вероятно, пароли хранятся в БД в открытом виде посколькусравниваютполеpassнапрямуюпоскольку сравнивают поле pass напрямуюпосколькусравниваютполеpassнапрямую — это критично.SELECT * — может возвращать больше данных, чем требуется.Скорее всего, отсутствуют: проверка/ограничение ошибок, ограничение прав БД-пользователя, защита от брутфорса.2) Типы атак, которые допускает такой код высокоуровнево,безпошаговыхэксплойтоввысокоуровнево, без пошаговых эксплойтоввысокоуровнево,безпошаговыхэксплойтов
SQL-инъекция вцеломв целомвцелом. Позволяет манипулировать SQL-запросом, изменить логику WHERE, прочитать/изменить/удалить данные, выполнять нежелательные запросы.Подвиды SQL-инъекции:Тавтологические/авторизационные обходы: злоумышленник может изменить условие так, чтобы оно всегда было истинно чтопозволяетобходитьаутентификациючто позволяет обходить аутентификациючтопозволяетобходитьаутентификацию.Выборочные UNION−подобныеUNION-подобныеUNION−подобные и ошибка-ориентированные инъекции: используются для вытаскивания данных из других таблиц.Слепая boolean−based/time−basedboolean-based / time-basedboolean−based/time−based инъекция: когда сервер не выдаёт прямой результат, атакующий получает информацию побитово по ответам сервера/времени ответа.Множественные/стековые запросы еслиСУБД/драйверразрешаютесли СУБД/драйвер разрешаютеслиСУБД/драйверразрешают — позволяют выполнить несколько операторов.Перехват и брутфорс паролей
Если пароли хранятся в открытом виде, компрометация БД = компрометация всех паролей.Отсутствие ограничений на число попыток позволяет брутфорс и credential stuffing.Информационное раскрытие / разведка
Ошибки SQL и подробные сообщения могут раскрывать схему БД, имена таблиц/полей, признаки используемой СУБД.Вторичные уязвимости
Если полученные из БД данные потом выводятся в HTML без экранирования — возможен XSS.Если входные данные используются в shell-командах или LDAP/OS-командах — возможны другие инъекции.Тайминговые/криптографические атаки
Если сравнение паролей выполняется небезопасно не−константноевремяне-константное времяне−константноевремя, возможны утечки информации через тайминговые атаки.
3) Влияние / последствия успешной атаки
Полный компромисс БД: чтение всех пользователей и паролей, персональных данных и т. п.Аутентификация обходится — злоумышленник получает доступ к аккаунтам.Модификация данных, создание/удаление записей.Утечка резервных данных и последующие массовые взломы еслипаролинехешированыесли пароли не хешированыеслипаролинехешированы.Возможный RCE/эскалация привилегий взависимостиотокруженияв зависимости от окружениявзависимостиотокружения.4) Как защищать — общие принципы
Никогда не конкатенировать пользовательский ввод в SQL.Хранить пароли только в виде криптографически безопасных хэшей Argon2id/bcrypt/scryptArgon2id / bcrypt / scryptArgon2id/bcrypt/scrypt, с уникальной солью для каждой записи.Использовать параметризованные запросы preparedstatementsprepared statementspreparedstatements или ORM с безопасной привязкой параметров.Минимизировать привилегии учётной записи БД, которую использует приложение толькоSELECT/UPDATE/INSERTдлянужныхтаблицтолько SELECT/UPDATE/INSERT для нужных таблицтолькоSELECT/UPDATE/INSERTдлянужныхтаблиц.Ограничивать выдачу подробных SQL-ошибок пользователю — логировать их на сервер.Вводить защиту от брутфорса: rate limiting, задержки, блокировка аккаунта, CAPTCHA.Использовать HTTPS, HSTS, безопасные cookie HttpOnly,Secure,SameSiteHttpOnly, Secure, SameSiteHttpOnly,Secure,SameSite, и многофакторную аутентификацию MFAMFAMFA.Включить мониторинг, WAF и аудит запросов/логов.Проводить проверку и тестирование на уязвимости SAST/DAST/пентестSAST/DAST/пентестSAST/DAST/пентест.5) Практические безопасные варианты реализации аутентификации
На этапе регистрации: хешировать пароль безопасным алгоритмом и сохранять только хэш и соль еслиалгоритмтребуетесли алгоритм требуетеслиалгоритмтребует, НЕ хранить plain.На этапе логина:Ниже — безопасная логика в общем виде:
Получить запись пользователя по логину параметризованныйзапроспараметризованный запроспараметризованныйзапрос.Если запись есть — проверить введённый пароль с сохранённым хэшем с помощью безопасной функции верификации котораяделаетвнутреннийсоль/итерациикоторая делает внутренний соль/итерациикотораяделаетвнутреннийсоль/итерации.Выполнить проверку учёта блокировок/locked/disabled и, при успехе, создать сессию/токен.
Примеры безопасного подхода псевдо/безопасныйкодпсевдо/безопасный кодпсевдо/безопасныйкод:
PHP PDOPDOPDO + хэширование passwordhash/passwordverifypassword_hash / password_verifypasswordh ash/passwordv erify:
Подготовленный запрос: SELECT id, password_hash FROM users WHERE login = :loginЗатем password_verify($pass, $row['password_hash'])Библиотека password_hash поддерживает bcrypt / Argon2 на современных PHP.Python psycopg2psycopg2psycopg2 + argon2:
cursor.execute("SELECT id, password_hash FROM users WHERE login = %s", (login,))Использовать библиотеку argon2-cffi для сравнения: argon2.PasswordHasher.verifyhash,passwordhash, passwordhash,passwordJava JDBCJDBCJDBC + PreparedStatement:
PreparedStatement stmt = conn.prepareStatement("SELECT id, password_hash FROM users WHERE login = ?");stmt.setString1,login1, login1,login;Результат -> проверка хеша с библиотекой BCrypt/Argon2.Node.js pg/mysql2pg/mysql2pg/mysql2 + bcrypt/argon2:
client.query('SELECT id, password_hash FROM users WHERE login = $1', [login])await argon2.verifyhash,passwordhash, passwordhash,passwordвкаждомпримереважныподготовленныезапросыиотдельнаяпроверкахешанасервере—никогданевключайтепарольвSQLдлясравненияв каждом примере важны подготовленные запросы и отдельная проверка хеша на сервере — никогда не включайте пароль в SQL для сравнениявкаждомпримереважныподготовленныезапросыиотдельнаяпроверкахешанасервере—никогданевключайтепарольвSQLдлясравнения
6) Дополнительные меры и хорошие практики
Не показывайте детальные ошибки аутентификации «internalerror»,«SQLerror»«internal error», «SQL error»«internalerror»,«SQLerror». Для пользователя — общие сообщения «неверныеучётныеданные»«неверные учётные данные»«неверныеучётныеданные».Логируйте подозрительную активность и включите алерты.Применяйте принцип наименьших привилегий для БД-пользователя нетправDROP/SHOW/CREATE,еслиненужнынет прав DROP/SHOW/CREATE, если не нужнынетправDROP/SHOW/CREATE,еслиненужны.Отключите возможность выполнения нескольких SQL-операторов одним запросом, если драйвер/СУБД позволяет.Внедрите MFA и защищённые сессионные токены JWTскороткимсрокомилисерверныесессииJWT с коротким сроком или серверные сессииJWTскороткимсрокомилисерверныесессии.Регулярно обновляйте зависимости, СУБД и используемые библиотеки хеширования.Рассмотрите использование специализированных провайдеров аутентификации OAuth/OpenIDConnect,внешниеIdentity−платформыOAuth/OpenID Connect, внешние Identity-платформыOAuth/OpenIDConnect,внешниеIdentity−платформы при необходимости.7) Заключение — конкретные шаги, которые нужно выполнить прямо сейчас
Перейти на параметризованные запросы preparedstatementsprepared statementspreparedstatements для любых SQL-запросов с вводом пользователей.Пересмотреть хранение паролей — если пароли в БД не хешированы, срочно потребовать смены пароля и заменить хранение на Argon2/bcrypt.Отключить показ SQL-ошибок пользователям; добавить логирование.Ввести защиту от брутфорса rate−limiting,блокировки,CAPTCHArate-limiting, блокировки, CAPTCHArate−limiting,блокировки,CAPTCHA и MFA.Провести аудит привилегий БД и ограничить права приложения.Выполнить тестирование безопасности сканирование/пентестсканирование/пентестсканирование/пентест.Если хотите, могу:
Показать конкретные безопасные примеры кода для языка/стека, который вы используете (PHP/Java/Python/Node/C#).Сформулировать чек-лист по исправлению уязвимости и по hardening-аутентификации.