Skip to content

🎯 可达性分析

可达性模块评估漏洞经依赖图可达的直接程度——从直接使用 API(direct)到 not_reachable。它定义 ReachabilityLevel 类型及其常量、ReachabilityResultReachabilitySummary 结构体、可插拔的 ReachabilityAnalyzer 接口、默认实现 DependencyGraphReachabilityAnalyzer,以及批量与汇总辅助函数。

类型:ReachabilityLevel

go
type ReachabilityLevel string

描述漏洞可达的直接程度。

常量

go
const (
    ReachabilityDirect       ReachabilityLevel = "direct"
    ReachabilityTransitive   ReachabilityLevel = "transitive"
    ReachabilityConditional  ReachabilityLevel = "conditional"
    ReachabilityNotReachable ReachabilityLevel = "not_reachable"
    ReachabilityUnknown      ReachabilityLevel = "unknown"
)
常量说明
ReachabilityDirectdirect漏洞位于直接使用的 API 中
ReachabilityTransitivetransitive漏洞位于传递性依赖中
ReachabilityConditionalconditional仅在特定条件下可达
ReachabilityNotReachablenot_reachable漏洞不可达
ReachabilityUnknownunknown无法判定可达性

类型:ReachabilityResult

go
type ReachabilityResult struct {
    Vulnerability *VulnerabilityFinding `json:"vulnerability"`
    Level         ReachabilityLevel     `json:"level"`
    Path          []string              `json:"path,omitempty"`
    Evidence      string                `json:"evidence,omitempty"`
    Confidence    float64               `json:"confidence"`
}
字段类型说明
Vulnerability*VulnerabilityFinding被分析的漏洞发现
LevelReachabilityLevel可达性评估结果
Path[]string从根到受影响组件的调用/依赖路径
Evidencestring可达性判定依据
Confidencefloat64评估置信度(0.01.0

类型:ReachabilityAnalyzer

go
type ReachabilityAnalyzer interface {
    Analyze(graph *DependencyGraph, findings []*VulnerabilityFinding) ([]*ReachabilityResult, error)
    AnalyzeComponent(graph *DependencyGraph, component *SBOMComponent, findings []*VulnerabilityFinding) ([]*ReachabilityResult, error)
}

可插拔的可达性分析接口,允许从简单依赖图遍历到完整静态分析的多种实现。

类型:DependencyGraphReachabilityAnalyzer

go
type DependencyGraphReachabilityAnalyzer struct {
    MaxDepth               int
    IncludeDevDependencies bool
}

默认的轻量级分析器,适用于多数 SCA 场景。依据组件是直接还是传递依赖来判定可达性。

字段类型说明
MaxDepthint最大分析依赖深度(0 = 不限)
IncludeDevDependenciesbool是否包含开发依赖

类型:ReachabilitySummary

go
type ReachabilitySummary struct {
    Total            int    `json:"total"`
    Direct           int    `json:"direct"`
    Transitive       int    `json:"transitive"`
    Conditional      int    `json:"conditional"`
    NotReachable     int    `json:"notReachable"`
    Unknown          int    `json:"unknown"`
    HighestRiskLevel string `json:"highestRiskLevel"`
}
字段类型说明
Totalint分析的漏洞总数
Directint直接可达漏洞数
Transitiveint传递可达漏洞数
Conditionalint条件可达漏洞数
NotReachableint不可达漏洞数
Unknownint可达性未知漏洞数
HighestRiskLevelstring数量大于 0 的最高风险可达等级

🆕 NewDependencyGraphReachabilityAnalyzer

go
func NewDependencyGraphReachabilityAnalyzer() *DependencyGraphReachabilityAnalyzer

创建默认分析器:深度不限(MaxDepth == 0)、排除开发依赖。

返回值类型说明
#1*DependencyGraphReachabilityAnalyzer新的默认分析器
go
a := cpeskills.NewDependencyGraphReachabilityAnalyzer()

🔬 Analyze

go
func (a *DependencyGraphReachabilityAnalyzer) Analyze(graph *DependencyGraph, findings []*VulnerabilityFinding) ([]*ReachabilityResult, error)

针对依赖图分析所有漏洞发现的可达性。会先重算节点深度。每个发现按 CVE CPE 或 OSV 包名匹配到图节点并评估,未匹配的发现记为 ReachabilityUnknown

参数类型说明
graph*DependencyGraph依赖图
findings[]*VulnerabilityFinding待评估的漏洞发现
返回值类型说明
#1[]*ReachabilityResult每个发现的可达性结果
#2errorgraph 为 nil 时非 nil
go
results, err := analyzer.Analyze(graph, findings)
if err != nil {
    log.Fatal(err)
}
for _, r := range results {
    fmt.Println(r.Level, r.Confidence)
}

🔬 AnalyzeComponent

go
func (a *DependencyGraphReachabilityAnalyzer) AnalyzeComponent(graph *DependencyGraph, component *SBOMComponent, findings []*VulnerabilityFinding) ([]*ReachabilityResult, error)

针对图中单个组件节点分析漏洞发现的可达性。

参数类型说明
graph*DependencyGraph依赖图
component*SBOMComponent待评估的组件
findings[]*VulnerabilityFinding待评估的漏洞发现
返回值类型说明
#1[]*ReachabilityResult每个发现的可达性结果
#2errorgraph 为 nil 或组件不在图中时非 nil
go
results, err := analyzer.AnalyzeComponent(graph, comp, findings)

⚡ QuickReachabilityCheck

go
func QuickReachabilityCheck(graph *DependencyGraph, component *SBOMComponent, finding *VulnerabilityFinding) *ReachabilityResult

便捷函数,用默认分析器评估单个组件/发现。任何错误都返回 ReachabilityUnknownConfidence == 0.0 的结果。

参数类型说明
graph*DependencyGraph依赖图
component*SBOMComponent待评估的组件
finding*VulnerabilityFinding单个待评估发现
返回值类型说明
#1*ReachabilityResult可达性结果(永不为 nil)
go
r := cpeskills.QuickReachabilityCheck(graph, comp, finding)
fmt.Println(r.Level, r.Evidence)

📦 BatchReachabilityAnalysis

go
func BatchReachabilityAnalysis(graphs []*DependencyGraph, findings []*VulnerabilityFinding) (map[string][]*ReachabilityResult, error)

对多个依赖图执行可达性分析,适用于每个子项目各有依赖图的 monorepo 场景。结果键取自第一个直接根节点的组件名,回退为 graph-<index>

参数类型说明
graphs[]*DependencyGraph待分析的依赖图
findings[]*VulnerabilityFinding待评估的漏洞发现
返回值类型说明
#1map[string][]*ReachabilityResult图名到结果的映射
#2error始终为 nil;单图失败对应 nil
go
results, _ := cpeskills.BatchReachabilityAnalysis(graphs, findings)
for name, rs := range results {
    fmt.Println(name, len(rs))
}

📊 SummarizeReachability

go
func SummarizeReachability(results []*ReachabilityResult) *ReachabilitySummary

将可达性结果汇总,按等级计数并确定最高风险等级。

参数类型说明
results[]*ReachabilityResult待汇总的结果
返回值类型说明
#1*ReachabilitySummary汇总结果
go
summary := cpeskills.SummarizeReachability(results)
fmt.Printf("direct=%d transitive=%d highest=%s\n", summary.Direct, summary.Transitive, summary.HighestRiskLevel)

✅ GetActionableFindings

go
func GetActionableFindings(results []*ReachabilityResult) []*VulnerabilityFinding

筛选可采取行动的发现——等级不为 ReachabilityNotReachable 的结果。(保留 ReachabilityUnknown 的发现,因其值得调查。)

参数类型说明
results[]*ReachabilityResult待筛选的结果
返回值类型说明
#1[]*VulnerabilityFindingnot_reachable 的发现
go
actionable := cpeskills.GetActionableFindings(results)
for _, f := range actionable {
    fmt.Println(f.CVE.CVEID)
}

📐 可达性等级图

Released under the MIT License.