简单说两句
今年公司开始推进程序依赖组件的漏洞修复,结合内部的devops流程我们开发了SCA系统,并以此扫描推动组件cve漏洞的升级工作。在这过程中,总是会有使用maven构建管理的java项目开发同学求助修复中遇到的各种各样小问题。下文中列举了2个我遇到的小例子,希望能帮助到遇到相同问题的筒子们。
(2020.2.2 春节后疫情中的通州)
开始正文
基础知识普及
什么是maven?
Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
Maven 依赖管理
pom.xml 的 dependencies 列表列出了我们的项目需要构建的所有外部依赖项。我们可以在pom.xml中的dependencies标签指定依赖的组件名称、版本等。如:
<dependencies>
<!-- 在这里添加你的依赖 -->
<dependency>
<groupId>ldapjdk</groupId> <!-- 库名称,也可以自定义 -->
<artifactId>ldapjdk</artifactId> <!--库名称,也可以自定义-->
<version>1.0</version> <!--版本号-->
<scope>system</scope> <!--作用域-->
<systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath> <!--项目根目录下的lib文件夹下-->
</dependency>
</dependencies>
问题一 父子依赖传递的坑
- 场景:升级某组件,以jackson举例,在项目根目录下的 pom 已经声明了高版本的组件,模块中也修改了相应的高版本,但是通过mvn dependency:tree 命令扫描还是会出现低版本的组件依赖。
如下配置
1)根 pom 配置,已经修改为2.10.3的版本
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.10.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2)java模块内 pom 配置也都修改为2.10.3版本
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.10.3</version>
</dependency>
3)然而配置完成后,通过 mvn dependency:tree 查看版本依赖,jackson-databind 还是低版本的
[INFO] +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.10.3:compile
[INFO] | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.0:compile
[INFO] | +- com.fasterxml.jackson.core:jackson-core:jar:2.8.11:compile
[INFO] | \- com.fasterxml.jackson.core:jackson-databind:jar:2.8.11.2:compile
- 原因:后来查了些资料,发现这是由于根 pom 中引用了父依赖 spring-boot-starter-parent ,且这个依赖会传递一堆 starter 过来,其中 jackson-databind 恰好是用的 2.8.11.2 版本。而 spring boot parent 里的<dependency Management>指定了各组件的版本号,这个优先级要高于传递依赖的版本。所以导致 jackson-databind 版本依然是这个依赖指定的版本。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
我们看下maven官网这个org.springframework.boot 对应版本的jackson依赖正好是2.8.11.2版本,印证了这个问题的根源。
- 解决办法:使用 <dependency Management>在 pom 里指定 jackson 版本。
备注:<dependency Management>有先后优先级顺序。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.10.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
问题二 java模块相互依赖传递的坑
- 场景:多模块项目,模块A中引用了模块B,模块B引用了风险组件 xx,那么在模块B中修改xx组件的版本号,mvn dependency:tree 查看仍旧会显示老版本的组件风险。
- 原因:只修改了模块B版本号的话,模块A中应用的还是模块B中的老版本。
- 解决办法:一并修改A模块的依赖版本
结语
安全运营工作中会遇到很多细节和坑,团队处理这些问题的经验往往难以形成有效的沉淀。导致相同的问题会反复出现,这样不仅消耗运营人员大量的工作经历,对公司安全问题的推进也无裨益。如果能建立起安全知识库并和公司的devops流程相结合,长期运行下来肯定会形成良性的循环。
更多maven依赖相关的知识,推荐大家可以参考maven的官方文档和这个手册,本人读后获益良多:https://www.runoob.com/maven/maven-tutorial.html。今天就到这里,感谢大家。