检测依赖项内部的漏洞对于创建安全的应用程序至关重要。除此之外,静态代码分析工具和预定义规则可以帮助您确保质量。幸运的是,有Maven插件可用于在您的构建中自动执行此操作。通过此博客文章,我将向您展示我的前三个Maven插件,以确保质量和安全性。
为了查看这三个Maven插件的实际使用,我使用Java 11和以下依赖项创建了一个Spring Boot Maven项目:
<?xml version=<font>"1.0"</font><font> encoding=</font><font>"UTF-8"</font><font>?> <project xmlns=</font><font>"http://maven.apache.org/POM/4.0.0"</font><font> xmlns:xsi=</font><font>"http://www.w3.org/2001/XMLSchema-instance"</font><font> xsi:schemaLocation=</font><font>"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"</font><font>> <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> </font>
除了用于启动Spring Boot应用程序的标准Java类之外,我还添加了第二个类来读取文件并在启动时打印输出:
@Component <b>public</b> <b>class</b> BadPracticeFileReader implements CommandLineRunner { @Override <b>public</b> <b>void</b> run(String... args) throws Exception { InputStream in = <b>this</b>.getClass().getResourceAsStream(<font>"/message.txt"</font><font>); byte[] allBytes = in.readAllBytes(); System.out.println(<b>new</b> String(allBytes)); } } </font>
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=<font>"1.0"</font><font> encoding=</font><font>"UTF-8"</font><font>?> <suppressions xmlns=</font><font>"https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.2.xsd"</font><font>> <!-- example to suppress a false warning <suppress> <notes><![CDATA[ Suppress all dependencies <b>for</b> CVE-2018-1258 (https:</font><font><i>//pivotal.io/security/cve-2018-1258)</i></font><font> ]]></notes> <cve>CVE-2018-1258</cve> </suppress> --> </suppressions> </font>
包括插件如下所示:
<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><b>true</b></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相关的博客文章。