Код-ревью Middle Инъекции: SQL, NoSQL, команды обновлено

Ревью: репозиторий на Java

Вопрос

Найдите проблемы в методе поиска заказов.

public List<Order> find(String status, String sortBy) throws SQLException {
    String sql = "SELECT * FROM orders WHERE status = ? ORDER BY " + sortBy;
    PreparedStatement ps = conn.prepareStatement(sql);
    ps.setString(1, status);
    ResultSet rs = ps.executeQuery();
    List<Order> res = new ArrayList<>();
    while (rs.next()) res.add(map(rs));
    return res;
}

Коротко

Частая ловушка: разработчик считает запрос безопасным, потому что использует PreparedStatement, но часть запроса всё равно собирается конкатенацией. Параметризация покрывает только значения.

Что должен найти ревьюер

  1. Безопасностьстрока 2
    Значение status параметризовано, но sortBy вклеено в SQL: инъекция через сортировку. Нужен allowlist колонок и направления.
  2. Безопасностьстрока 2
    Нет фильтра по владельцу: метод отдаёт заказы всех клиентов, если вызывающий код не ограничит.
  3. Стильстрока 2
    SELECT * тянет все колонки, включая служебные, лучше явный список.
  4. Ошибкастрока 5
    PreparedStatement и ResultSet не закрываются: нужен try-with-resources, иначе утечка соединений.

Разбор

Частая ловушка: разработчик считает запрос безопасным, потому что использует PreparedStatement, но часть запроса всё равно собирается конкатенацией. Параметризация покрывает только значения.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.