Я пытаюсь реализовать один из сценариев с использованием java-кода. Я пишу плохой код, чтобы проанализировать его через sonarqube.
Я попытался протестировать «SQL-запросы не должны быть уязвимы для атак путем инъекций» из https://rules.sonarsource.com/java/tag/SonarSecurity/RSPEC-3649. Ниже приведен код, который я пытаюсь проанализировать.
package group;
import java.util.*;
import java.io.PrintStream;
import java.nio.file.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import javax.naming.*;
public class SonarDemo {
public static void main(String[] args) {
PrintStream o = System.out; //NOSONAR
String pass = args[0];//request.getParameter("pass");
String user = args[1];
String query = "SELECT * FROM users WHERE user = '" + user + "' AND pass = '" + pass + "'"; // Unsafe
Properties connectionProps = new Properties();
connectionProps.put("user", user);
connectionProps.put("password", pass);
java.sql.Connection connection = null;
try {
connection = java.sql.DriverManager.getConnection("jdbc:localhost:sql1;create=true",connectionProps);
java.sql.Statement statement = connection.createStatement();
java.sql.ResultSet resultSet = statement.executeQuery(query);
Files.exists(Paths.get("/home/", user));
String filter = "(&(uid = " + user + ")(userPassword = " + pass + "))"; // Unsafe
LdapContext ctx = new InitialLdapContext();
NamingEnumeration<SearchResult> results = ctx.search("ou=system", filter, new SearchControls());
} catch (Exception e){
o.println("Exception");
}
}
}
Но есть некоторая проблема в коде, когда sonarqube не может получить этот код и показать, что существует проблема с атакой инъекции.
Как изменить этот код, чтобы создать некоторую атаку с использованием SQL-инъекций, чтобы мой sonarqube мог отображать эту ошибку на панели инструментов?
Короче говоря, изменение приведенного выше кода для создания атаки путем инъекции, как упоминалось здесь https://rules.sonarsource.com/java/tag/SonarSecurity/RSPEC-3649
Или вы можете установить pass на ' OR '1' = '1 и выбрать, чтобы вернуть все записи. Не уверен, что statement.executeQuery() выполнит сразу два запроса (выбор и удаление)
В зависимости от вашей базы данных замените -- на #.
Атаки с использованием SQL-инъекций происходят из-за использования некоторой формы необработанного ввода с SQL-запросами, а не из-за простого объединения строк. Подготовленные запросы - это всего лишь один из способов очистки ввода, возможно, самый простой, но не единственный способ.
Спасибо @Andonaeus и @ Ivan. Это похоже на тестовый пример, мне действительно не нужно использовать базу данных. Но я просто имитирую что-то, чтобы показать, как происходит атака SQL-инъекцией.
Код, который вы тестируете, действительно уязвим для атак с использованием SQL-инъекций. Sonarqube не может обнаружить ваш сценарий SQL-инъекции, это не означает, что он безопасен.
@SazzadurRahaman Я согласен с тем, что здесь происходит некоторая инъекция. Теперь я пытаюсь изменить этот код, чтобы сонар мог улавливать и показывать проблему, о которой я упоминал в вопросе. Спасибо!
@SazzadurRahaman, Действительно, есть старая цитата Эдсгера Дийсктры 1969 года: «Тестирование показывает наличие, а не отсутствие ошибок». Вы правы в том, что такой инструмент, как Sonarqube, не обязательно может найти 100% уязвимостей SQL-инъекций.
@BillKarwin, именно так! Ни один из инструментов анализа программы не идеален. У каждого из них есть очень четко определенная модель угроз (по крайней мере, все хорошие). Если выйдешь за его пределы - БУМ!




User provided data such as URL parameters should always be considered as untrusted and tainted.
Аргументы времени выполнения AFAIK не распознаются как вводимые пользователем. Чтобы воспроизвести проблему, попробуйте взять Пользователь и проходить из параметров URL-адреса запроса.
public boolean authenticate(javax.servlet.http.HttpServletRequest request, java.sql.Connection connection) throws SQLException {
String user = request.getParameter("user");
String pass = request.getParameter("pass");
}
Я попробую
В этой конкретной строке
String query = "SELECT * FROM users WHERE user = '" + user + "' AND pass = '" + pass + "'"; // Unsafe
вместо использования + для конкатенирования строки используйте StringBuilder и его метод добавления к конкатенированной строке, что позволит избежать атаки с использованием SQL-инъекций.
OP не пытается выполнить предотвращать атаку с использованием SQL-инъекции, используя этот код; наоборот; они намеренно представляют собой уязвимый код создание в контролируемой среде, чтобы они могли проверить работоспособность сканирующего инструмента (сонаркуба).
К сожалению, я не читал правильно, но тогда, если это так, то приведенное выше может привести к ошибке атаки SQL-инъекции в сонаре.
Это как раз суть сообщения ОП; почему этот уязвимый код не определяется как уязвимый? Спрашивают «Но есть некоторая проблема в коде, когда sonarqube не может получить этот код и показать, что существует проблема с атакой инъекции»?
Я не понимаю, как StringBuilder может предотвратить инъекционную атаку; он не ведет себя иначе, чем +, он просто более эффективен.
Не сработает, если установить пароль на что-то вроде
"pass; DROP TABLE Users; --"