Статьи

Устранение распространенных нарушений кода безопасности Java в Sonar

Цель этой статьи — показать, как быстро исправить наиболее распространенные нарушения кода безопасности Java. Предполагается, что вы знакомы с концепцией правил и нарушений кода и с тем, как Sonar сообщает о них. Однако, если вы не слышали этих терминов раньше, вы можете взглянуть на Sonar Concepts или на будущую книгу о Sonar для более подробного объяснения.

Чтобы понять, во время анализа 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 .