Чтобы понять, во время анализа Sonar ваш проект сканируется многими инструментами, чтобы убедиться, что исходный код соответствует правилам, которые вы создали в своем профиле качества . Всякий раз, когда правило нарушается … ну, нарушение возникает. С помощью Sonar вы можете отслеживать эти нарушения, просматривая нарушения или в редакторе исходного кода. Существуют сотни правил, классифицированных в зависимости от их важности. В следующих статьях я постараюсь охватить как можно больше, но сейчас давайте рассмотрим некоторые общие правила / нарушения безопасности. Есть две пары правил (все они оцениваются как критические в сонаре), которые мы собираемся рассмотреть прямо сейчас.
1. Массив хранится напрямую ( PMD ), а метод возвращает внутренний массив ( PMD )
Эти нарушения появляются в тех случаях, когда внутренний массив сохраняется или возвращается непосредственно из метода. В следующем примере показан простой класс, который нарушает эти правила.
|
1
2
3
4
5
6
7
8
9
|
public class CalendarYear { private String[] months; public String[] getMonths() { return months; } public void setMonths(String[] months) { this.months = months; }} |
Чтобы устранить их, вы должны клонировать массив перед его сохранением / возвратом, как показано в следующей реализации класса, чтобы никто не мог изменить или получить исходные данные вашего класса, а только их копию.
|
1
2
3
4
5
6
7
8
9
|
public class CalendarYear { private String[] months; public String[] getMonths() { return months.clone(); } public void setMonths(String[] months) { this.months = months.clone(); }} |
2. Непостоянная строка, переданная методу выполнения в операторе SQL ( findbugs ), и подготовленный оператор генерируется из непостоянной строки (findbugs )
Оба правила связаны с доступом к базе данных при использовании библиотек JDBC. Как правило, существует два способа выполнения командлетов SQL через соединение JDBC: Statement и PreparedStatement. Существует много дискуссий о плюсах и минусах, но это выходит за рамки этого поста. Давайте посмотрим, как возникает первое нарушение, основываясь на следующем фрагменте исходного кода.
|
1
2
3
|
Statement stmt = conn.createStatement();String sqlCommand = 'Select * FROM customers WHERE name = '' + custName + ''';stmt.execute(sqlCommand); |
Вы уже заметили, что параметр sqlcommand, передаваемый методу execute, динамически создается во время выполнения, что неприемлемо для этого правила. Подобные ситуации вызывают второе нарушение.
|
1
2
|
String sqlCommand = 'insert into customers (id, name) values (?, ?)';Statement stmt = conn.prepareStatement(sqlCommand); |
Вы можете преодолеть эту проблему тремя различными способами. Вы можете использовать метод StringBuilder или String.format для создания значений строковых переменных. Если применимо, вы можете определить команды SQL как константы в объявлении класса, но это только для случая, когда команду SQL не требуется изменять во время выполнения. Давайте перепишем первый фрагмент кода, используя StringBuilder
|
1
2
3
4
|
Statement stmt = conn.createStatement();stmt.execute(new StringBuilder('Select FROM customers WHERE name = ''). append(custName). append(''').toString()); |
и используя String.format
|
1
2
3
|
Statement stmt = conn.createStatement();String sqlCommand = String.format('Select * from customers where name = '%s'', custName);stmt.execute(sqlCommand); |
Для второго примера вы можете просто объявить sqlCommand следующим образом
|
1
|
private static final SQLCOMMAND = insert into customers (id, name) values (?, ?)'; |
Существуют и другие правила безопасности, такие как блокирующий постоянный пароль базы данных, жестко закодированный, но я предполагаю, что никто не все еще жестко кодирует пароли в файлах исходного кода
В следующих статьях я собираюсь показать вам, как придерживаться правил производительности и плохой практики. До тех пор я жду ваших комментариев или предложений.
Приятного кодирования и не забудьте поделиться!
Справка: Устранение распространенных нарушений кода безопасности Java в Sonar от нашего партнера JCG Папапетру П. Патроклоса в блоге Only Software .