引言
在现代软件开发中,多语言混合开发已成为常态。Go、Java和
一、Go语言依赖扫描
1.1 扫描类型支持
Trivy支持两种Go项目的扫描方式:
-
Go Modules扫描:通过分析 go.mod
和go.sum
文件 -
Go二进制文件扫描:分析编译后的可执行文件
Go Modules扫描支持SBOM生成、漏洞检测和许可证检查,而二进制扫描则不支持许可证检查。
1.2 技术实现细节
1.2.1 Go Modules扫描
对于不同版本的Go项目,Trivy采用不同的解析策略:
-
Go 1.17+: 仅需 go.mod
文件即可获取直接和间接依赖 -
Go 1.16及以下:需要 go.mod
获取直接依赖,go.sum
获取间接依赖
这种差异源于Go 1.17+在go.mod中只保留实际需要的间接依赖,减少了误报可能。
// go.mod示例module github.com/aquasecurity/trivygo1.18require ( github.com/CycloneDX/cyclonedx-go v0.5.0// ...)
1.2.2 标准库检测
Trivy通过分析go.mod中的go和toolchain指令来推断使用的Go标准库版本。这一功能仅在--detection-priority comprehensive模式下启用,且仅支持Go 1.21+版本。
1.2.3 二进制扫描
Trivy能够解析Go工具在构建时嵌入二进制文件中的依赖和版本信息:
$ trivy rootfs ./your_binary
需要注意的是,UPX压缩的二进制文件无法被扫描。
1.2.4 特殊处理
主模块检测:Trivy默认不扫描项目自身的漏洞,只扫描其依赖项 版本检测:对于go install安装的二进制文件能正确获取版本,其他情况可能版本为空 许可证检测:需要预先下载模块到本地缓存(如go mod download)
二、Java依赖扫描
2.1 扫描类型支持
Trivy支持四种Java项目扫描方式:
* JAR/WAR/PAR/EAR文件 * pom.xml * gradle.lock文件 * sbt.lock文件
查看项目所有的软件包信息
trivy --debug fs --list-all-pkgs --format json -o output.json .
2.2 技术实现细节
2.2.1 JAR文件扫描
Trivy通过解析JAR文件中的pom.properties和MANIFEST.MF获取依赖信息。当这些文件信息不足时,会查询Trivy Java数据库(自动下载/更新)。
// 典型JAR文件结构META-INF/ MANIFEST.MForg/ example/ MyClass.classpom.properties
2.2.2 pom.xml解析
Trivy会从以下位置查找依赖:
-
项目目录 -
relativePath字段指定路径 -
本地 Maven 仓库 -
当本地找不到依赖时,Trivy会尝试从远程仓库获取信息,包括:pom文件中指定的仓库、 Maven 中央仓库
2.2.3 Gradle和SBT扫描
gradle.lock:仅包含使用的依赖信息,扫描完全离线
sbt.lock:需要sbt-dependency-lock插件生成的锁文件
2.2.4 特殊处理
-
作用域过滤:只扫描import、compile、runtime和空作用域的依赖 -
版本处理:无法确定版本时使用空版本,且不扫描其子依赖 -
开发依赖:默认排除,可通过--include-dev-deps启用
三、Python 依赖扫描
3.1 扫描类型支持
Trivy支持如下
包管理器:
-
pip (requirements.txt) -
Pipenv (Pipfile.lock) -
Poetry (poetry.lock) -
uv (uv.lock)
包格式:
-
Egg -
Wheel -
Conda
3.2 技术实现细节
3.2.1 pip扫描
Trivy默认只解析使用==且不带.*的版本说明符。在--detection-priority comprehensive模式下,会解析更多版本格式:
keyring >= 4.1.1 # 最低版本4.1.1Mopidy-Dirble ~= 1.1 # 最低版本1.1python -gitlab==2.0.* # 最低版本2.0.0
对于获取完整依赖树,推荐使用pip freeze或pip-compile:
$ pip install -r requirements.txt$ pip freeze > requirements.txt
3.2.2 Pipenv/Poetry/uv扫描
-
Pipenv:解析Pipfile.lock,不支持许可证检测 -
Poetry:需要poetry.lock和pyproject.toml共同构建依赖图 -
uv:解析uv.lock文件
3.2.3 包格式扫描
-
Egg:查找*.egg-info、PKG-INFO等文件 -
Wheel:解析.dist-info/METADATA文件
3.2.4 特殊处理
-
开发依赖:默认包含pip/Pipenv的,排除Poetry/uv的 -
许可证检测:通过检查site-packages目录中的METADATA文件实现 -
虚拟环境:优先检查VIRTUAL_ENV环境变量
四、扫描能力对比
4.1 最佳实践建议
4.1.1 Go项目:
-
升级到Go 1.17+以获得更准确的间接依赖检测 -
对于二进制文件,使用go install确保版本信息正确嵌入
4.1.2 Java项目:
-
使用锁文件(gradle.lock/sbt.lock)确保依赖一致性 -
对于 Maven 项目,确保关键依赖版本明确指定
4.1.3 Python 项目:
使用pip freeze或pip-compile生成完整依赖列表 生产环境扫描时使用--skip-dev-deps排除开发依赖
4.1.4 通用建议:
-
定期更新Trivy数据库获取最新漏洞信息 -
对于误报问题,合理使用ignore文件或VEX Hub
4.2 结语
Trivy通过针对不同语言特性的定制化解析策略,实现了高效准确的多语言依赖扫描。理解其背后的技术原理,有助于开发者更好地利用这一工具提升项目安全性, 为软件供应链安全提供更强保障。
参考文档
-
https://trivy.dev/latest/docs/ -
https://trivy.dev/latest/tutorials/overview/
原文始发于微信公众号(SDL安全):Trivy多语言依赖扫描技术原理解析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论