可确保项目的质量和安全性的三个Maven插件 - rieckpil


检测依赖项内部的漏洞对于创建安全的应用程序至关重要。除此之外,静态代码分析工具和预定义规则可以帮助您确保质量。幸运的是,有Maven插件可用于在您的构建中自动执行此操作。通过此博客文章,我将向您展示我的前三个Maven插件,以确保质量和安全性。

为了查看这三个Maven插件的实际使用,我使用Java 11和以下依赖项创建了一个Spring Boot Maven项目:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=
"http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
 
    <groupId>de.rieckpil.blog</groupId>
    <artifactId>maven-plugins-to-ensure-quality</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven-plugins-to-ensure-quality</name>
 
    <properties>
        <java.version>11</java.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

除了用于启动Spring Boot应用程序的标准Java类之外,我还添加了第二个类来读取文件并在启动时打印输出:

@Component
public class BadPracticeFileReader implements CommandLineRunner {
 
    @Override
    public void run(String... args) throws Exception {
        InputStream in = this.getClass().getResourceAsStream("/message.txt");
        byte[] allBytes = in.readAllBytes();
        System.out.println(new String(allBytes));
    }
}

Maven Enforcer插件
Maven的强制实施的插件检查几个预定义的规则像在构建期间检查Java,Maven或OS版本一样简单(在此处查找所有规则的列表)。同样,您可以使用此插件将项目中禁止的一组依赖项列入黑名单。一个很好的用例是在从JUnit 4过渡到JUnit 5之后。一旦所有测试都使用JUnit 5,就可以排除JUnit 4依赖关系并创建一条规则,这样其他队友就不会再因意外而包含它。
接下来,您可以使用dependencyConvergenceMaven Enforcer插件中的规则来确保项目中只有一个版本的依赖项可用。一旦您的项目扩展并包含更多的依赖项,例如,在引入不同版本的Jackson时可能会有两个依赖项。这可能是一个问题,因为默认的类加载器只会在它可以找到的类路径上选择第一个。
为了检测这种情况,该dependencyConvergence规则将失败,并显示适当的控制台输出。然后,您可以通过将依赖项版本固定在dependencyManagement或从一个依赖项中排除它来解决此问题。
您可以像下面这样将该插件包含到您的项目中:

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-enforcer-plugin</artifactId>
   <configuration>
      <rules>
         <bannedDependencies>
            <excludes>
               <exclude>junit:junit</exclude>
               <exclude>junit:junit-dep</exclude>
            </excludes>
         </bannedDependencies>
         <dependencyConvergence />
      </rules>
   </configuration>
   <executions>
      <execution>
         <goals>
            <goal>enforce</goal>
         </goals>
      </execution>
   </executions>
</plugin>

一旦运行mvn verify或mvn enforcer:enforce检查配置的规则。

OWASP依赖性检查以确保依赖性质量
您添加到项目中的依赖项越多,您越有可能必须处理常见漏洞和披露(CVE)。手动检查CVE数据库是否有新问题很麻烦。幸运的是,有一个免费的Maven插件可以在构建期间执行此操作:OWASP Dependency-Check Maven插件。此插件会分析您的所有依赖关系,并且一旦其中一个依赖关系成为CVE的一部分,就会使构建失败(如果已配置)或产生日志警告。
请注意,这些漏洞是从NIST托管的国家漏洞数据库(NVD)中下载的:https//nvd.nist.gov。第一次运行可能需要花费几分钟,如果您打算使用它,则一定要为CI / CD管道启用缓存。过去,我们还观察到了该托管漏洞数据库的一些停机时间。在这种情况下,我们将插件配置为不会使构建失败。
此外,可能仅针对特定的依赖项设置或操作系统会发生漏洞。为了消除这种假阳性,可以将owasp-suppressions.xml文件添加到项目中,并排除以下CVE:

<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns=
"https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.2.xsd">
    <!-- example to suppress a false  warning
    <suppress>
        <notes><![CDATA[
         Suppress all dependencies for CVE-2018-1258 (https:
//pivotal.io/security/cve-2018-1258)
        ]]></notes>
        <cve>CVE-2018-1258</cve>
    </suppress>
     -->
</suppressions>

包括插件如下所示:

<plugin>
   <groupId>org.owasp</groupId>
   <artifactId>dependency-check-maven</artifactId>
   <version>5.2.2</version>
   <configuration>
      <suppressionFiles>
         <suppressionFile>owasp-suppressions.xml</suppressionFile>
      </suppressionFiles>
      <failBuildOnCVSS>8</failBuildOnCVSS>
      <assemblyAnalyzerEnabled>false</assemblyAnalyzerEnabled>
      <failOnError>true</failOnError>
   </configuration>
   <executions>
      <execution>
         <goals>
            <goal>check</goal>
         </goals>
      </execution>
   </executions>
</plugin>

使用failBuildOnCVSS配置值,您可以指定使构建失败的CVE的严重性。分数范围从0到10。
一旦运行mvn verify或对mvn depencency-check:check您的依赖关系进行了分析。

SpotBugs Maven插件可确保代码质量
拥有静态代码分析工具可能有助于修复潜在的错误。除了SonarQube,还有一个流行的Maven插件,不需要进一步设置:SpotBugs Maven插件(以前称为FindBugs)。
从个人经验来看,我不会因为静态代码分析工具而使构建失败。宁时不时检查可能的警告并修复最明显的警告。
您可以使用以下配置包括此Maven插件:

<plugin>
   <groupId>com.github.spotbugs</groupId>
   <artifactId>spotbugs-maven-plugin</artifactId>
   <version>3.1.12.2</version>
   <dependencies>
      <dependency>
         <groupId>com.github.spotbugs</groupId>
         <artifactId>spotbugs</artifactId>
         <version>4.0.0-beta4</version>
      </dependency>
   </dependencies>
</plugin>

现在,您可以运行  mvn spotbugs:check以分析您的源代码。此外,您可以启动一个简单的UI来分析潜在的代码分析警告mvn spotbugs:gui。
在我们的示例中,SpotBugs抱怨BadPracticeFileReader该类的实现。当我们在字节数组之外创建String时使用默认编码时,它检测到三个潜在的错误,并且没有正确清理打开的资源。
您可以在GitHub找到此博客文章的源代码。在此处查找其他与Maven相关的博客文章。