Skip to content

vector 包

vector 包提供了 CVSS 指标的统一接口和具体实现。它定义了所有 CVSS 3.x 指标的行为和属性,为解析器和计算器提供了基础的数据结构。

包概述

go
import "github.com/scagogogo/cvss-parser/pkg/vector"

核心接口

Vector 接口

所有 CVSS 指标都实现了 Vector 接口:

go
type Vector interface {
    GetGroupName() string    // 获取指标组名称
    GetShortName() string    // 获取指标简称
    GetLongName() string     // 获取指标全称
    GetShortValue() rune     // 获取指标简写值
    GetLongValue() string    // 获取指标完整值
    GetDescription() string  // 获取指标描述
    GetScore() float64       // 获取指标评分
    String() string          // 字符串表示
}

详细文档:Vector 接口

指标分类

基础指标 (Base Metrics)

基础指标描述了漏洞的固有特征,不随时间或环境变化。

可利用性指标

指标简称实现类型可能值
攻击向量AVAttackVector*Network, Adjacent, Local, Physical
攻击复杂性ACAttackComplexity*Low, High
所需权限PRPrivilegesRequired*None, Low, High
用户交互UIUserInteraction*None, Required

影响指标

指标简称实现类型可能值
范围SScope*Unchanged, Changed
机密性影响CConfidentiality*None, Low, High
完整性影响IIntegrity*None, Low, High
可用性影响AAvailability*None, Low, High

时间指标 (Temporal Metrics)

时间指标反映了漏洞随时间变化的特征。

指标简称实现类型可能值
利用代码成熟度EExploitCodeMaturity*Not Defined, Unproven, Proof-of-Concept, Functional, High
修复级别RLRemediationLevel*Not Defined, Official Fix, Temporary Fix, Workaround, Unavailable
报告置信度RCReportConfidence*Not Defined, Unknown, Reasonable, Confirmed

环境指标 (Environmental Metrics)

环境指标允许根据特定环境自定义评分。

环境需求指标

指标简称实现类型可能值
机密性需求CRConfidentialityRequirement*Not Defined, Low, Medium, High
完整性需求IRIntegrityRequirement*Not Defined, Low, Medium, High
可用性需求ARAvailabilityRequirement*Not Defined, Low, Medium, High

修改后的基础指标

所有基础指标都有对应的修改版本,前缀为 Modified

  • ModifiedAttackVector*
  • ModifiedAttackComplexity*
  • ModifiedPrivilegesRequired*
  • 等等...

使用示例

创建指标实例

go
// 创建攻击向量指标
attackVector := &vector.AttackVectorNetwork{}
fmt.Printf("攻击向量: %s (%s)\n", 
    attackVector.GetLongValue(), 
    attackVector.GetDescription())

// 创建攻击复杂性指标
attackComplexity := &vector.AttackComplexityLow{}
fmt.Printf("攻击复杂性: %s (评分: %.2f)\n", 
    attackComplexity.GetLongValue(), 
    attackComplexity.GetScore())

使用接口

go
func printVectorInfo(v vector.Vector) {
    fmt.Printf("指标: %s (%s)\n", v.GetLongName(), v.GetShortName())
    fmt.Printf("  组: %s\n", v.GetGroupName())
    fmt.Printf("  值: %s (%c)\n", v.GetLongValue(), v.GetShortValue())
    fmt.Printf("  评分: %.2f\n", v.GetScore())
    fmt.Printf("  字符串: %s\n", v.String())
}

// 使用示例
av := &vector.AttackVectorNetwork{}
printVectorInfo(av)

向量工厂

go
type VectorFactory struct{}

func (f *VectorFactory) CreateAttackVector(value rune) (vector.Vector, error) {
    switch value {
    case 'N':
        return &vector.AttackVectorNetwork{}, nil
    case 'A':
        return &vector.AttackVectorAdjacent{}, nil
    case 'L':
        return &vector.AttackVectorLocal{}, nil
    case 'P':
        return &vector.AttackVectorPhysical{}, nil
    default:
        return nil, fmt.Errorf("未知的攻击向量值: %c", value)
    }
}

指标详细信息

攻击向量 (Attack Vector)

描述攻击者如何访问漏洞组件。

go
// 网络攻击向量
type AttackVectorNetwork struct{}
func (a *AttackVectorNetwork) GetShortValue() rune { return 'N' }
func (a *AttackVectorNetwork) GetScore() float64 { return 0.85 }

// 相邻网络攻击向量
type AttackVectorAdjacent struct{}
func (a *AttackVectorAdjacent) GetShortValue() rune { return 'A' }
func (a *AttackVectorAdjacent) GetScore() float64 { return 0.62 }

// 本地攻击向量
type AttackVectorLocal struct{}
func (a *AttackVectorLocal) GetShortValue() rune { return 'L' }
func (a *AttackVectorLocal) GetScore() float64 { return 0.55 }

// 物理攻击向量
type AttackVectorPhysical struct{}
func (a *AttackVectorPhysical) GetShortValue() rune { return 'P' }
func (a *AttackVectorPhysical) GetScore() float64 { return 0.2 }

攻击复杂性 (Attack Complexity)

描述攻击成功所需的条件。

go
// 低复杂性
type AttackComplexityLow struct{}
func (a *AttackComplexityLow) GetShortValue() rune { return 'L' }
func (a *AttackComplexityLow) GetScore() float64 { return 0.77 }

// 高复杂性
type AttackComplexityHigh struct{}
func (a *AttackComplexityHigh) GetShortValue() rune { return 'H' }
func (a *AttackComplexityHigh) GetScore() float64 { return 0.44 }

影响指标

影响指标描述了成功攻击对系统的影响程度。

go
// 机密性影响
type ConfidentialityHigh struct{}
func (c *ConfidentialityHigh) GetShortValue() rune { return 'H' }
func (c *ConfidentialityHigh) GetScore() float64 { return 0.56 }

type ConfidentialityLow struct{}
func (c *ConfidentialityLow) GetShortValue() rune { return 'L' }
func (c *ConfidentialityLow) GetScore() float64 { return 0.22 }

type ConfidentialityNone struct{}
func (c *ConfidentialityNone) GetShortValue() rune { return 'N' }
func (c *ConfidentialityNone) GetScore() float64 { return 0.0 }

向量验证

基本验证

go
func validateVector(v vector.Vector) error {
    if v.GetShortName() == "" {
        return fmt.Errorf("指标简称不能为空")
    }
    
    if v.GetShortValue() == 0 {
        return fmt.Errorf("指标值不能为空")
    }
    
    score := v.GetScore()
    if score < 0 || score > 1 {
        return fmt.Errorf("指标评分必须在 0-1 之间,当前值: %.2f", score)
    }
    
    return nil
}

批量验证

go
func validateVectors(vectors []vector.Vector) []error {
    var errors []error
    
    for i, v := range vectors {
        if err := validateVector(v); err != nil {
            errors = append(errors, fmt.Errorf("向量 %d 验证失败: %w", i, err))
        }
    }
    
    return errors
}

向量比较

基本比较

go
func compareVectors(v1, v2 vector.Vector) {
    fmt.Printf("比较 %s%s:\n", v1.String(), v2.String())
    
    if v1.GetShortName() != v2.GetShortName() {
        fmt.Println("  不同类型的指标,无法比较")
        return
    }
    
    score1 := v1.GetScore()
    score2 := v2.GetScore()
    
    if score1 > score2 {
        fmt.Printf("  %s (%.2f) > %s (%.2f)\n", 
            v1.GetDescription(), score1, v2.GetDescription(), score2)
    } else if score1 < score2 {
        fmt.Printf("  %s (%.2f) < %s (%.2f)\n", 
            v1.GetDescription(), score1, v2.GetDescription(), score2)
    } else {
        fmt.Printf("  %s = %s (%.2f)\n", 
            v1.GetDescription(), v2.GetDescription(), score1)
    }
}

向量分组

go
func groupVectorsByType(vectors []vector.Vector) map[string][]vector.Vector {
    groups := make(map[string][]vector.Vector)
    
    for _, v := range vectors {
        groupName := v.GetGroupName()
        groups[groupName] = append(groups[groupName], v)
    }
    
    return groups
}

扩展和自定义

自定义向量

go
// 自定义向量实现
type CustomVector struct {
    groupName   string
    shortName   string
    longName    string
    shortValue  rune
    longValue   string
    description string
    score       float64
}

func (c *CustomVector) GetGroupName() string { return c.groupName }
func (c *CustomVector) GetShortName() string { return c.shortName }
func (c *CustomVector) GetLongName() string { return c.longName }
func (c *CustomVector) GetShortValue() rune { return c.shortValue }
func (c *CustomVector) GetLongValue() string { return c.longValue }
func (c *CustomVector) GetDescription() string { return c.description }
func (c *CustomVector) GetScore() float64 { return c.score }
func (c *CustomVector) String() string {
    return fmt.Sprintf("%s:%c", c.shortName, c.shortValue)
}

向量注册表

go
type VectorRegistry struct {
    vectors map[string]map[rune]vector.Vector
}

func NewVectorRegistry() *VectorRegistry {
    return &VectorRegistry{
        vectors: make(map[string]map[rune]vector.Vector),
    }
}

func (r *VectorRegistry) Register(shortName string, value rune, v vector.Vector) {
    if r.vectors[shortName] == nil {
        r.vectors[shortName] = make(map[rune]vector.Vector)
    }
    r.vectors[shortName][value] = v
}

func (r *VectorRegistry) Get(shortName string, value rune) (vector.Vector, bool) {
    if group, exists := r.vectors[shortName]; exists {
        if v, found := group[value]; found {
            return v, true
        }
    }
    return nil, false
}

性能优化

向量缓存

go
var vectorCache = make(map[string]vector.Vector)
var cacheMutex sync.RWMutex

func getCachedVector(key string) (vector.Vector, bool) {
    cacheMutex.RLock()
    defer cacheMutex.RUnlock()
    
    v, exists := vectorCache[key]
    return v, exists
}

func setCachedVector(key string, v vector.Vector) {
    cacheMutex.Lock()
    defer cacheMutex.Unlock()
    
    vectorCache[key] = v
}

对象池

go
var vectorPool = sync.Pool{
    New: func() interface{} {
        return &vector.AttackVectorNetwork{}
    },
}

func getVectorFromPool() vector.Vector {
    return vectorPool.Get().(vector.Vector)
}

func putVectorToPool(v vector.Vector) {
    vectorPool.Put(v)
}

最佳实践

1. 类型安全

go
func getAttackVectorScore(v vector.Vector) (float64, error) {
    if v.GetShortName() != "AV" {
        return 0, fmt.Errorf("不是攻击向量指标")
    }
    return v.GetScore(), nil
}

2. 空值处理

go
func safeGetScore(v vector.Vector) float64 {
    if v == nil {
        return 0.0
    }
    return v.GetScore()
}

3. 接口组合

go
type CVSSVector interface {
    vector.Vector
    IsRequired() bool
    GetCategory() string
}

相关文档

Released under the MIT License.