Skip to content

Commit

Permalink
feat: 支持trivy输出license扫描结果 #28
Browse files Browse the repository at this point in the history
  • Loading branch information
cnlkl committed Mar 24, 2023
1 parent cfeb428 commit 13a664e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 14 deletions.
12 changes: 11 additions & 1 deletion trivy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,14 @@
---

最后在蓝鲸制品库Admin中配置`Standard`类型的扫描器,
启动命令为`/bkrepo-trivy`,参考trivy Air-Gapped Environment配置文档下载`db.tar.gz``javadb.tar.gz`传到制品分析服务可访问的路径,比如某个制品仓库中,并添加`STRING`类型的参数`dbDownloadUrl``javaDbDownloadUrl`指定trivy漏洞库`db.tar.gz``javadb.tar.gz`的下载地址
启动命令为`/bkrepo-trivy`,参考trivy Air-Gapped Environment配置文档下载`db.tar.gz``javadb.tar.gz`传到制品分析服务可访问的路径,比如放在某个制品仓库中

#### 制品库Admin中增加参数

| 参数名 | 类型 | 默认值 | 说明 |
|-------------------|---------|-------|----------------------------------------------------|
| dbDownloadUrl | STRING || 漏洞库db.tar.gz下载地址 |
| javaDbDownloadUrl | STRING || 漏洞库javadb.tar.gz下载地址 |
| scanSensitive | BOOLEAN | false | 是否开启敏感信息扫描 |
| scanLicense | BOOLEAN | false | 是否开启License扫描,开启后会扫描apk、apt、npm、pip等安装的依赖包的License |
| licenseFull | BOOLEAN | false | 是否扫描所有文本文件License,开启后会导致扫描耗时增加 |
20 changes: 16 additions & 4 deletions trivy/pkg/constant/trivy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ const FlagInput = "--input"
// FlagCacheDir 指定trivy缓存目录
const FlagCacheDir = "--cache-dir"

// FlagSecurityChecks 指定扫描类型
const FlagSecurityChecks = "--security-checks"
// FlagScanners 指定使用的扫描器
const FlagScanners = "--scanners"

// FlagLicenseFull 指定是否扫描所有文本文件
const FlagLicenseFull = "--license-full"

// FlagSkipDbUpdate 跳过更新trivy.db
const FlagSkipDbUpdate = "--skip-db-update"
Expand Down Expand Up @@ -59,12 +62,21 @@ const FormatJson = "json"
// OutputPath 输出文件路径
const OutputPath = util.WorkDir + "/trivy-output.json"

// CheckVuln 检查安全漏洞
const CheckVuln = "vuln"
// ScannerVuln 漏洞扫描器
const ScannerVuln = "vuln"

// ScannerSecret 敏感信息扫描器
const ScannerSecret = "secret"

// ScannerLicense 许可证扫描器
const ScannerLicense = "license"

// ClassSecret 敏感信息结果类型
const ClassSecret = "secret"

// ClassLicense 许可扫描结果
const ClassLicense = "license"

// ArgDbDownloadUrl 漏洞库下载地址
const ArgDbDownloadUrl = "dbDownloadUrl"

Expand Down
32 changes: 32 additions & 0 deletions trivy/pkg/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Result struct {
Type string `json:"Type"`
Vulnerabilities []Vulnerability `json:"Vulnerabilities"`
Secrets []Secret `json:"Secrets"`
Licenses []License `json:"Licenses"`
}

// Vulnerability trivy扫描漏洞
Expand Down Expand Up @@ -77,6 +78,17 @@ type Secret struct {
Match string `json:"Match"`
}

// License trivy许可扫描结果
type License struct {
Severity string `json:"Severity"`
Category string `json:"Category"`
PkgName string `json:"PkgName"`
FilePath string `json:"FilePath"`
Name string `json:"Name"`
Confidence float64 `json:"Confidence"`
Link string `json:"Link"`
}

// ConvertToToolResults 转换trivy扫描结果为工具框架标准扫描结果
func ConvertToToolResults(output *Output) *object.Result {
toolResults := new(object.Result)
Expand All @@ -91,6 +103,11 @@ func ConvertToToolResults(output *Output) *object.Result {
toolResults.SensitiveResults =
append(toolResults.SensitiveResults, *ConvertToSensitiveResult(&secret, result.Target))
}
} else if result.Class == constant.ClassLicense {
for _, license := range result.Licenses {
toolResults.LicenseResults =
append(toolResults.LicenseResults, *ConvertToLicenseResult(&license, result.Target))
}
} else {
for _, vulnerability := range result.Vulnerabilities {
toolResults.SecurityResults =
Expand Down Expand Up @@ -134,3 +151,18 @@ func ConvertToSensitiveResult(secret *Secret, path string) *object.SensitiveResu
Content: secret.Match,
}
}

// ConvertToLicenseResult 转换trivy许可扫描结果为工具框架许可扫描结果
func ConvertToLicenseResult(license *License, path string) *object.LicenseResult {
var licensePath string
if len(license.FilePath) > 0 {
licensePath = license.FilePath
} else {
licensePath = path + " : " + license.PkgName
}
return &object.LicenseResult{
LicenseName: license.Name,
Path: licensePath,
PkgName: license.PkgName,
}
}
33 changes: 24 additions & 9 deletions trivy/pkg/scan_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/TencentBlueKing/ci-repoAnalysis/trivy/pkg/constant"
"os"
"path/filepath"
"strings"
)

// TrivyExecutor Trivy分析工具执行器实现
Expand All @@ -22,13 +23,8 @@ func (e TrivyExecutor) Execute(config *object.ToolConfig, file *os.File) (*objec
return nil, err
}
}
maxTime, err := config.GetIntArg("maxTime")
if err != nil {
return nil, err
}
scanSensitive, _ := config.GetBoolArg("scanSensitive")

if err := execTrivy(file.Name(), maxTime, scanSensitive, offline); err != nil {
if err := execTrivy(file.Name(), offline, config); err != nil {
return nil, err
}
return transformOutputJson()
Expand All @@ -51,10 +47,18 @@ func downloadAllDB(config *object.ToolConfig) error {
return nil
}

func execTrivy(fileName string, maxTime int64, scanSensitive bool, offline bool) error {
func execTrivy(fileName string, offline bool, config *object.ToolConfig) error {
// trivy --cache-dir /root/.cache/trivy image --input filePath -f json
// -o /bkrepo/workspace/trivy-output.json --skip-db-update --offline-scan

maxTime, err := config.GetIntArg("maxTime")
if err != nil {
return err
}
scanSensitive, _ := config.GetBoolArg("scanSensitive")
scanLicense, _ := config.GetBoolArg("scanLicense")
licenseFull, _ := config.GetBoolArg("licenseFull")

args := []string{
constant.FlagCacheDir, constant.CacheDir,
constant.SubCmdImage,
Expand All @@ -68,10 +72,21 @@ func execTrivy(fileName string, maxTime int64, scanSensitive bool, offline bool)
args = append(args, constant.FlagSkipDbUpdate, constant.FlagSkipJavaDbUpdate, constant.FlagOfflineScan)
}

if !scanSensitive {
args = append(args, constant.FlagSecurityChecks, constant.CheckVuln)
// 设置要使用的扫描器
scanners := []string{constant.ScannerVuln}
if scanSensitive {
scanners = append(scanners, constant.ScannerSecret)
}
if scanLicense {
scanners = append(scanners, constant.ScannerLicense)
}
args = append(args, constant.FlagScanners, strings.Join(scanners, ","))

if scanLicense && licenseFull {
args = append(args, constant.FlagLicenseFull)
}

// 指定敏感信息规则
if _, err := os.Stat(constant.SecretRuleFilePath); !errors.Is(err, os.ErrNotExist) {
args = append(args, constant.FlagSecretConfig, constant.SecretRuleFilePath)
}
Expand Down

0 comments on commit 13a664e

Please sign in to comment.