Как защититься от SQL инъекции
Что проверяют
Понимаете ли вы, откуда берётся инъекция: данные попадают в текст запроса и становятся кодом. Интервьюер ждёт, что главным средством вы назовёте параметризацию, а не фильтрацию ввода. Следом обычно спрашивают, как быть с сортировкой по имени колонки и безопасен ли Hibernate сам по себе.
Как отвечать
Основа: запрос и данные передаются раздельно, и значение не может изменить структуру SQL.
- JDBC:
PreparedStatementс плейсхолдерами?иsetString,setLong. Драйвер отправляет параметры отдельно или корректно экранирует их сам; - Spring:
JdbcTemplateс?,NamedParameterJdbcTemplateс:name, в Spring Data JPA методы-запросы и@Queryс параметрами; - JPA и Hibernate:
setParameterв JPQL и нативных запросах, Criteria API. Hibernate защищает, только пока вы не склеиваете строку сами вcreateQueryилиcreateNativeQuery; - MyBatis:
#{}подставляет параметр, а${}вставляет текст как есть, это прямая дыра.
Отдельно разберите места, где плейсхолдер не работает. Имена таблиц, колонок и направление сортировки параметризовать нельзя, поэтому их берут из белого списка: Map допустимых значений от клиента к имени колонки. Для IN с переменным числом значений генерируют нужное число ? или в PostgreSQL передают массив через = ANY(?). Для LIKE параметром передаётся весь шаблон вместе с %.
Вторая линия обороны: учётная запись базы с минимальными правами, без DDL и доступа к чужим схемам, ошибки SQL не отдаются клиенту, а статический анализ вроде SonarQube или SpotBugs с плагином Find Security Bugs ловит склейку строк до ревью.
Где спотыкаются
Называют главной защитой валидацию и ручное экранирование. Это дополнительные меры: экранирование легко сломать кодировкой или забытым случаем, а валидация не спасает поле, где допустим любой текст.
Считают, что ORM защищает автоматически. Строка "from User where name = '" + name + "'" в HQL уязвима так же, как в JDBC.
Показывают пример с WHERE password = ?. Параметризация там верная, но пароль не должен лежать в базе открытым текстом: хранят хеш через BCrypt или Argon2 и сравнивают в приложении.