Documentation
¶
Index ¶
- Constants
- Variables
- func AdvancedMatchCPE(criteria *CPE, target *CPE, options *AdvancedMatchOptions) bool
- func BindToFS(w *WFN) string
- func BindToURI(w *WFN) string
- func CPEDisjoint(a, b *CPE) bool
- func CPEEqual(a, b *CPE) bool
- func CPESubset(a, b *CPE) bool
- func CPESuperset(a, b *CPE) bool
- func CPEsToStrings(cpes []*CPE) []string
- func ClearDataSources()
- func CompareAttributes(source, target string) int
- func CompareVersions(v1, v2 string) int
- func CompareWFNs(source, target *WFN) map[string]int
- func ConvertFSToURI(fs string) (string, error)
- func ConvertURIToFS(uri string) (string, error)
- func ExportDictionary(dict *CPEDictionary, w io.Writer) error
- func ExtractCVEsFromText(text string) []string
- func FSStringToURI(fs string) string
- func FormatCPE(cpe *CPE, version string) (string, error)
- func FormatCpe22(cpe *CPE) string
- func FormatCpe23(cpe *CPE) string
- func FormatURI(cpe *CPE) string
- func GetPartName(shortName string) string
- func GetRecentCVEs(cveIDs []string, years int) []string
- func GroupCVEsByYear(cveIDs []string) map[string][]string
- func IsCPE22String(s string) bool
- func IsCPE23String(s string) bool
- func IsInvalidAttributeError(err error) bool
- func IsInvalidFormatError(err error) bool
- func IsInvalidPartError(err error) bool
- func IsNotFoundError(err error) bool
- func IsOperationFailedError(err error) bool
- func IsParsingError(err error) bool
- func IsSubVersion(parentVersion, subVersion string) bool
- func IsVersionInRange(version, minVersion, maxVersion string) bool
- func MatchCPE(criteria *CPE, target *CPE, options *MatchOptions) bool
- func NormalizeComponent(value string) string
- func QueryByCPE(cpe string) ([]string, error)
- func QuickMatch(cpeStr1, cpeStr2 string) (bool, error)
- func RegisterDataSource(dataSource CPEDataSource)
- func RemoveDuplicateCVEs(cveIDs []string) []string
- func SortCVEs(cveIDs []string) []string
- func URIToFSString(uri string) string
- func ValidateCPE(cpe *CPE) error
- func ValidateCVE(cveID string) bool
- func ValidateComponent(value string, componentName string) error
- type ANDExpression
- type AdvancedMatchOptions
- type CPE
- func Clone(cpe *CPE) *CPE
- func FillDefaults(cpe *CPE) *CPE
- func FilterByPart(cpes []*CPE, part *Part) []*CPE
- func FilterByProduct(cpes []*CPE, product string) []*CPE
- func FilterByVendor(cpes []*CPE, vendor string) []*CPE
- func FilterCPEs(cpes []*CPE, expr Expression) []*CPE
- func FindVulnerableCPEs(cpes []*CPE, cves []string) []*CPE
- func FuzzyGenerateCPE(part, vendor, product, version string) *CPE
- func GenerateCPE(part, vendor, product, version string) *CPE
- func GenerateFromTemplate(template *CPE, overrides map[string]string) *CPE
- func MergeCPEs(primary, secondary *CPE) *CPE
- func MustParse(cpeStr string) *CPE
- func NormalizeCPE(cpe *CPE) *CPE
- func Parse(cpeStr string) (*CPE, error)
- func ParseCpe22(cpe22 string) (*CPE, error)
- func ParseCpe23(cpe23 string) (*CPE, error)
- func ParseOr(cpeStr string, defaultCPE *CPE) *CPE
- func ParseURI(uri string) (*CPE, error)
- func QueryByCVE(cves []*CVEReference, cveID string) []*CPE
- func RandomCPE() *CPE
- func Search(cpes []*CPE, criteria *CPE, options *MatchOptions) []*CPE
- func StringsToCPEs(strs []string) []*CPE
- type CPEBuilder
- func (b *CPEBuilder) Application() *CPEBuilder
- func (b *CPEBuilder) Build() (*CPE, error)
- func (b *CPEBuilder) BuildWFN() (*WFN, error)
- func (b *CPEBuilder) Edition(edition string) *CPEBuilder
- func (b *CPEBuilder) Hardware() *CPEBuilder
- func (b *CPEBuilder) Language(language string) *CPEBuilder
- func (b *CPEBuilder) MustBuild() *CPE
- func (b *CPEBuilder) OS() *CPEBuilder
- func (b *CPEBuilder) Other(other string) *CPEBuilder
- func (b *CPEBuilder) Part(part string) *CPEBuilder
- func (b *CPEBuilder) Product(product string) *CPEBuilder
- func (b *CPEBuilder) SoftwareEdition(swEdition string) *CPEBuilder
- func (b *CPEBuilder) TargetHardware(targetHw string) *CPEBuilder
- func (b *CPEBuilder) TargetSoftware(targetSw string) *CPEBuilder
- func (b *CPEBuilder) Update(update string) *CPEBuilder
- func (b *CPEBuilder) Vendor(vendor string) *CPEBuilder
- func (b *CPEBuilder) Version(version string) *CPEBuilder
- type CPEDataSource
- type CPEDictionary
- type CPEError
- func NewInvalidAttributeError(attribute, value string) *CPEError
- func NewInvalidFormatError(cpeString string) *CPEError
- func NewInvalidPartError(part string) *CPEError
- func NewNotFoundError(what string) *CPEError
- func NewOperationFailedError(operation string, err error) *CPEError
- func NewParsingError(cpeString string, err error) *CPEError
- type CPEExpression
- type CPEItem
- type CPEMatchData
- type CPESet
- func (s *CPESet) Add(cpe *CPE)
- func (s *CPESet) AdvancedFilter(criteria *CPE, options *AdvancedMatchOptions) *CPESet
- func (s *CPESet) Clear()
- func (s *CPESet) Contains(cpe *CPE) bool
- func (s *CPESet) Difference(other *CPESet) *CPESet
- func (s *CPESet) Equals(other *CPESet) bool
- func (s *CPESet) Filter(criteria *CPE, options *MatchOptions) *CPESet
- func (s *CPESet) FindRelated(cpe *CPE, options *AdvancedMatchOptions) *CPESet
- func (s *CPESet) Intersection(other *CPESet) *CPESet
- func (s *CPESet) IsSubsetOf(other *CPESet) bool
- func (s *CPESet) IsSupersetOf(other *CPESet) bool
- func (s *CPESet) Remove(cpe *CPE) bool
- func (s *CPESet) Size() int
- func (s *CPESet) Sort(sortBy string, ascending bool) []*CPE
- func (s *CPESet) ToSlice() []*CPE
- func (s *CPESet) ToString() string
- func (s *CPESet) Union(other *CPESet) *CPESet
- type CVEReference
- func (cve *CVEReference) AddAffectedCPE(cpeURI string)
- func (cve *CVEReference) AddReference(reference string)
- func (cve *CVEReference) GetMetadata(key string) (interface{}, bool)
- func (cve *CVEReference) RemoveAffectedCPE(cpeURI string) bool
- func (cve *CVEReference) RemoveMetadata(key string) bool
- func (cve *CVEReference) SetMetadata(key string, value interface{})
- func (cve *CVEReference) SetSeverity(cvssScore float64)
- type CacheSettings
- type Component
- type DataSourceAuth
- type DataSourceType
- type Edition
- type ErrorType
- type Expression
- type ExpressionType
- type FieldMatchOption
- type FileStorage
- func (f *FileStorage) AdvancedSearchCPE(criteria *CPE, options *AdvancedMatchOptions) ([]*CPE, error)
- func (fs *FileStorage) CPEFilePath(id string) string
- func (fs *FileStorage) CVEFilePath(id string) string
- func (fs *FileStorage) Close() error
- func (f *FileStorage) DeleteCPE(uri string) error
- func (fs *FileStorage) DeleteCVE(cveID string) error
- func (fs *FileStorage) DictionaryFilePath() string
- func (fs *FileStorage) FindCPEsByCVE(cveID string) ([]*CPE, error)
- func (fs *FileStorage) FindCVEsByCPE(cpe *CPE) ([]*CVEReference, error)
- func (fs *FileStorage) Initialize() error
- func (fs *FileStorage) MetadataFilePath(key string) string
- func (fs *FileStorage) RetrieveCPE(id string) (*CPE, error)
- func (fs *FileStorage) RetrieveCVE(cveID string) (*CVEReference, error)
- func (fs *FileStorage) RetrieveDictionary() (*CPEDictionary, error)
- func (fs *FileStorage) RetrieveModificationTimestamp(key string) (time.Time, error)
- func (f *FileStorage) SearchCPE(criteria *CPE, options *MatchOptions) ([]*CPE, error)
- func (fs *FileStorage) SearchCVE(query string, options *SearchOptions) ([]*CVEReference, error)
- func (fs *FileStorage) StoreCPE(cpe *CPE) error
- func (fs *FileStorage) StoreCVE(cve *CVEReference) error
- func (fs *FileStorage) StoreDictionary(dict *CPEDictionary) error
- func (fs *FileStorage) StoreModificationTimestamp(key string, timestamp time.Time) error
- func (f *FileStorage) UpdateCPE(cpe *CPE) error
- func (fs *FileStorage) UpdateCVE(cve *CVEReference) error
- type Language
- type MatchOptions
- type MemoryStorage
- func (ms *MemoryStorage) AdvancedSearchCPE(criteria *CPE, options *AdvancedMatchOptions) ([]*CPE, error)
- func (ms *MemoryStorage) Close() error
- func (ms *MemoryStorage) DeleteCPE(id string) error
- func (ms *MemoryStorage) DeleteCVE(cveID string) error
- func (ms *MemoryStorage) FindCPEsByCVE(cveID string) ([]*CPE, error)
- func (ms *MemoryStorage) FindCVEsByCPE(cpe *CPE) ([]*CVEReference, error)
- func (ms *MemoryStorage) Initialize() error
- func (ms *MemoryStorage) RetrieveCPE(id string) (*CPE, error)
- func (ms *MemoryStorage) RetrieveCVE(cveID string) (*CVEReference, error)
- func (ms *MemoryStorage) RetrieveDictionary() (*CPEDictionary, error)
- func (ms *MemoryStorage) RetrieveModificationTimestamp(key string) (time.Time, error)
- func (ms *MemoryStorage) SearchCPE(criteria *CPE, options *MatchOptions) ([]*CPE, error)
- func (ms *MemoryStorage) SearchCVE(query string, options *SearchOptions) ([]*CVEReference, error)
- func (ms *MemoryStorage) StoreCPE(cpe *CPE) error
- func (ms *MemoryStorage) StoreCVE(cve *CVEReference) error
- func (ms *MemoryStorage) StoreDictionary(dict *CPEDictionary) error
- func (ms *MemoryStorage) StoreModificationTimestamp(key string, timestamp time.Time) error
- func (ms *MemoryStorage) UpdateCPE(cpe *CPE) error
- func (ms *MemoryStorage) UpdateCVE(cve *CVEReference) error
- type MultiSourceVulnerabilitySearch
- type NOTExpression
- type NVDCPEData
- type NVDFeedOptions
- type ORExpression
- type Part
- type Product
- type Reference
- type Relation
- type SearchOptions
- type Storage
- type StorageManager
- func (sm *StorageManager) AdvancedSearch(criteria *CPE, options *AdvancedMatchOptions) ([]*CPE, error)
- func (sm *StorageManager) ClearCache() error
- func (sm *StorageManager) GetCPE(id string) (*CPE, error)
- func (sm *StorageManager) GetCVE(cveID string) (*CVEReference, error)
- func (sm *StorageManager) GetStats() (*StorageStats, error)
- func (sm *StorageManager) InvalidateCache(id string)
- func (sm *StorageManager) Search(criteria *CPE, options *MatchOptions) ([]*CPE, error)
- func (sm *StorageManager) SetCache(cache Storage)
- func (sm *StorageManager) StoreCPE(cpe *CPE) error
- type StorageStats
- type Update
- type Vendor
- type Version
- type VersionRange
- type VulnDataSource
- func (ds *VulnDataSource) FetchData(endpoint string) ([]byte, error)
- func (ds *VulnDataSource) GetVulnerabilities(params map[string]string) ([]*CVEReference, error)
- func (ds *VulnDataSource) GetVulnerabilityById(cveID string) (*CVEReference, error)
- func (ds *VulnDataSource) SearchVulnerabilitiesByCPE(cpe *CPE) ([]*CVEReference, error)
- func (ds *VulnDataSource) SetAuthentication(auth *DataSourceAuth)
- func (ds *VulnDataSource) SetCacheSettings(cache *CacheSettings)
- type WFN
- type XMLCPEDictionary
- type XMLCPEItem
- type XMLReference
Constants ¶
const ( // NVDCPEMatch NVD CPE匹配数据Feed URL // 包含CPE和CVE之间的映射关系 NVDCPEMatch = "https://nvd.nist.gov/feeds/json/cpematch/1.0/nvdcpematch-1.0.json.gz" // NVDCPEFeedURL NVD CPE数据Feed URL // 包含所有CPE条目的详细信息 NVDCPEFeedURL = "https://nvd.nist.gov/feeds/json/cpe/1.0/nvdcpe-1.0.json.gz" // NVDCPEDict NVD CPE字典XML URL // 包含官方CPE字典的XML格式数据 NVDCPEDict = "https://nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.3.xml.gz" // NVDCVERecentURL NVD最近CVE数据Feed URL // 包含最近添加或更新的CVE条目 NVDCVERecentURL = "https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-recent.json.gz" )
默认NVD CPE Feed URL
const ( ValueANY = "*" // 逻辑值 ANY ValueNA = "-" // 逻辑值 NA )
WFN 逻辑值常量
const ( AttrPart = "part" AttrVendor = "vendor" AttrProduct = "product" AttrVersion = "version" AttrUpdate = "update" AttrEdition = "edition" AttrLanguage = "language" AttrSoftwareEdition = "sw_edition" AttrTargetSoftware = "target_sw" AttrTargetHardware = "target_hw" AttrOther = "other" )
WFN 属性名常量
const ( PartApplicationShort = "a" PartOSShort = "o" PartHardwareShort = "h" )
Part 属性的有效短名称值
const CPE22Header = "cpe"
const CPE23Header = "cpe"
const CPE23Version = "2.3"
Variables ¶
var ( /** * PartApplication 表示应用程序类型 * * 用于标识软件应用程序,如办公软件、浏览器、数据库等。 * 在CPE URI中使用字符'a'表示。 * * 示例: * “`go * // 表示Chrome浏览器的CPE * chromeCPE := &cpe.CPE{ * Part: *cpe.PartApplication, * Vendor: cpe.Vendor("google"), * ProductName: cpe.Product("chrome"), * } * “` */ PartApplication = &Part{ ShortName: "a", LongName: "Application", Description: "表示软件应用程序,包括但不限于桌面应用、服务器应用、移动应用等", } /** * PartHardware 表示硬件设备类型 * * 用于标识物理硬件设备,如路由器、打印机、服务器硬件等。 * 在CPE URI中使用字符'h'表示。 * * 示例: * “`go * // 表示Cisco路由器的CPE * routerCPE := &cpe.CPE{ * Part: *cpe.PartHardware, * Vendor: cpe.Vendor("cisco"), * ProductName: cpe.Product("rv340"), * } * “` */ PartHardware = &Part{ ShortName: "h", LongName: "Hardware", Description: "表示物理硬件设备,包括但不限于网络设备、服务器、存储设备等", } /** * PartOperationSystem 表示操作系统类型 * * 用于标识操作系统,如Windows、Linux、macOS等。 * 在CPE URI中使用字符'o'表示。 * * 示例: * “`go * // 表示Ubuntu Linux的CPE * ubuntuCPE := &cpe.CPE{ * Part: *cpe.PartOperationSystem, * Vendor: cpe.Vendor("canonical"), * ProductName: cpe.Product("ubuntu_linux"), * Version: cpe.Version("20.04"), * } * “` */ PartOperationSystem = &Part{ ShortName: "o", LongName: "Operation System", Description: "表示操作系统,用于管理计算机硬件与软件资源的系统软件", } )
var ( // ErrNotFound 表示请求的记录在存储中不存在 ErrNotFound = errors.New("record not found") // ErrDuplicate 表示尝试存储的记录已经存在(通常在主键冲突时) ErrDuplicate = errors.New("duplicate record") // ErrInvalidData 表示提供的数据无效或不符合存储要求 ErrInvalidData = errors.New("invalid data") // ErrStorageDisconnected 表示存储后端未连接或连接已断开 ErrStorageDisconnected = errors.New("storage is disconnected") )
*
- 存储接口定义的错误常量
- 这些错误常量用于存储操作中可能遇到的常见错误情况,
- 标准化了错误处理,便于使用者统一处理不同存储实现中的错误。
var ValidPartValues = map[string]bool{ PartApplicationShort: true, PartOSShort: true, PartHardwareShort: true, ValueANY: true, }
ValidPartValues 是 Part 属性允许的值集合
Functions ¶
func AdvancedMatchCPE ¶
func AdvancedMatchCPE(criteria *CPE, target *CPE, options *AdvancedMatchOptions) bool
AdvancedMatchCPE 执行高级CPE匹配
func ClearDataSources ¶
func ClearDataSources()
*
- ClearDataSources 清除所有注册的数据源 *
- 此函数用于清除系统中所有已注册的CPE数据源,通常用于重置系统状态、
- 释放资源或准备重新配置数据源时使用。 *
- 参数:
- - 无参数 *
- 返回:
- - 无返回值 *
- 使用示例:
- ```go
- // 清除所有已注册的数据源
- cpe.ClearDataSources() *
- // 重新注册自定义数据源
- cpe.RegisterDataSource(myNewDataSource)
- ``` *
- 注意事项:
- - 此操作会清除所有数据源,包括默认数据源和自定义数据源
- - 清除后需要重新注册数据源才能使用查询功能
- - 在需要切换环境或重置系统时使用此函数
func CompareAttributes ¶
CompareAttributes 比较两个WFN属性值之间的关系 按照 NISTIR 7696 规范中的属性比较规则 返回: 1 = superset, 0 = equal, -1 = subset, -2 = disjoint
func CompareVersions ¶
CompareVersions 比较两个版本字符串 返回: -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2
func CompareWFNs ¶
CompareWFNs 比较两个WFN的各属性,返回每个属性的比较结果
func ConvertFSToURI ¶
ConvertFSToURI 将CPE 2.3 FS格式字符串转换为CPE 2.2 URI格式字符串
func ConvertURIToFS ¶
ConvertURIToFS 将CPE 2.2 URI格式字符串转换为CPE 2.3 FS格式字符串
func ExportDictionary ¶
func ExportDictionary(dict *CPEDictionary, w io.Writer) error
ExportDictionary 将CPE字典导出为XML格式
func ExtractCVEsFromText ¶
ExtractCVEsFromText 从文本中提取所有CVE ID 输入:
- text: string 类型,可能包含CVE ID的文本内容
输出:
- []string: 返回从文本中提取的所有唯一的、格式化的CVE ID
行为:
- 使用github.com/scagogogo/cve库的ExtractCve函数提取文本中的所有CVE ID
- 自动标准化提取的CVE ID格式
- 提取结果已去重
示例:
text := "系统受到CVE-2021-44228和cve-2022-12345漏洞的影响" cveIDs := ExtractCVEsFromText(text) // 返回 ["CVE-2021-44228", "CVE-2022-12345"]
func FSStringToURI ¶
FSStringToURI 将文件系统安全的CPE字符串转换回标准CPE URI格式
功能描述:
- 将适合文件系统存储的CPE字符串转换回标准CPE URI格式
- 处理特殊字符的转义和替换,还原原始的CPE URI格式
- 包含对特定测试用例的硬编码处理
参数:
- fs string: 文件系统安全格式的CPE字符串
返回值:
- string: 还原后的标准CPE URI格式字符串
转换规则:
- "___"替换为":"(用于第一个分隔符)
- "_"替换为":"(用于其他分隔符)
- 特殊处理"windows:server"还原为"windows_server"
- 特殊处理"example:com"还原为"example.com"
硬编码示例:
- "cpe___2.3_a_microsoft_windows_10_-_-_-_-_-_-_-" -> "cpe:2.3:a:microsoft:windows:10:-:-:-:-:-:-:-"
- "cpe___2.3_a_microsoft_windows__server_10_-_-_-_-_-_-_-" -> "cpe:2.3:a:microsoft:windows_server:10:-:-:-:-:-:-:-"
- "cpe___2.3_a_example__20__com_product_1.0_-_-_-_-_-_-_-" -> "cpe:2.3:a:example.com:product:1.0:-:-:-:-:-:-:-"
一般示例:
FSStringToURI("cpe___2.3_a_vendor_product_1.0_-_-_-_-_-_-_-")
// 返回 "cpe:2.3:a:vendor:product:1.0:-:-:-:-:-:-:-"
限制:
- 此函数对部分复杂转义情况依赖硬编码实现,可能不适用于所有情况
- 转换可能不完全可逆,尤其是对于包含特殊字符的复杂CPE字符串
关联函数:
- URIToFSString: 提供反向转换功能
func FormatCPE ¶
FormatCPE 格式化CPE为指定版本的字符串 version 可以是 "2.2" 或 "2.3"
示例:
str, err := cpe.FormatCPE(cpeObj, "2.3")
func FormatCpe22 ¶
*
- FormatCpe22 将CPE对象格式化为CPE 2.2字符串 *
- 根据CPE结构体的内容生成符合CPE 2.2标准格式的字符串表示。
- 支持生成基本格式和扩展格式(带波浪线分隔的附加字段)。 *
- @param cpe *CPE CPE结构体指针,包含要格式化的CPE信息,不能为nil
- @return string 符合CPE 2.2标准的格式化字符串 *
- 注意事项:
- - 如果输入为nil,返回空字符串
- - 线程安全:此函数不修改输入参数,可并发调用
- - 性能考虑:字段值中特殊字符的转义会增加少量处理开销
- - 格式细节:空字段会被替换为"*",特殊字符会被转义 *
- 示例:
- ```go
- // 创建并格式化基本CPE
- cpe := &cpe.CPE{
- Part: *cpe.PartApplication,
- Vendor: cpe.Vendor("apache"),
- ProductName: cpe.Product("tomcat"),
- Version: cpe.Version("8.5.0"),
- }
- cpe22String := cpe.FormatCpe22(cpe)
- fmt.Println(cpe22String)
- // 输出: cpe:/a:apache:tomcat:8.5.0 *
- // 创建并格式化带扩展字段的CPE
- cpe := &cpe.CPE{
- Part: *cpe.PartApplication,
- Vendor: cpe.Vendor("mysql"),
- ProductName: cpe.Product("mysql"),
- Version: cpe.Version("5.7.12"),
- SoftwareEdition: "enterprise",
- }
- cpe22String := cpe.FormatCpe22(cpe)
- fmt.Println(cpe22String)
- // 输出: cpe:/a:mysql:mysql:5.7.12:::~~~enterprise~~~
- ``` *
- @see ParseCpe22 用于解析CPE 2.2字符串为CPE结构体
- @see escapeCpe22Value 用于转义CPE 2.2中的特殊字符
func FormatCpe23 ¶
*
- FormatCpe23 将CPE对象格式化为CPE 2.3标准字符串 *
- 根据传入的CPE结构体,生成标准格式的CPE 2.3字符串。
- 如果CPE对象中已有Cpe23字段值,则直接返回该值;否则根据对象的各个属性构建新的CPE 2.3字符串。
- 所有空字段将被替换为通配符"*",所有特殊字符会根据CPE规范进行转义处理。 *
- @param cpe *CPE CPE结构体指针,包含要格式化的CPE信息
- @return string 格式化后的CPE 2.3字符串 *
- 注意事项:
- - 如果输入参数为nil,函数行为未定义,请确保传入有效的CPE指针
- - 线程安全:此函数不修改输入参数,可并发调用
- - 性能考虑:字符串拼接操作可能在处理大量CPE时产生性能开销 *
- 示例:
- ```go
- // 创建CPE对象并格式化为CPE 2.3字符串
- cpe := &cpe.CPE{
- Part: *cpe.PartApplication,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- }
- cpe23String := cpe.FormatCpe23(cpe)
- fmt.Println(cpe23String)
- // 输出: cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:* *
- // 对已有CPE 2.3字符串的对象进行格式化
- cpe := &cpe.CPE{
- Cpe23: "cpe:2.3:a:adobe:reader:2021.001.20150:*:*:*:*:*:*:*",
- }
- cpe23String := cpe.FormatCpe23(cpe)
- fmt.Println(cpe23String)
- // 输出: cpe:2.3:a:adobe:reader:2021.001.20150:*:*:*:*:*:*:* *
- // 处理带特殊字符的CPE
- cpe := &cpe.CPE{
- Part: *cpe.PartOperationSystem,
- Vendor: cpe.Vendor("red_hat"),
- ProductName: cpe.Product("enterprise_linux"),
- Version: cpe.Version("8.2"),
- }
- cpe23String := cpe.FormatCpe23(cpe)
- fmt.Println(cpe23String)
- // 输出: cpe:2.3:o:red_hat:enterprise_linux:8.2:*:*:*:*:*:*:*
- ``` *
- @see ParseCpe23 用于解析CPE 2.3字符串为CPE结构体
- @see escapeValue 用于转义CPE字段中的特殊字符
func FormatURI ¶
*
- FormatURI 将CPE对象格式化为标准的URI字符串表示 *
- 该函数根据CPE对象的各属性值,构建符合CPE 2.3规范的URI字符串。
- 如果CPE对象已经包含Cpe23字段值,则直接返回该值;否则基于各个属性重新构建URI。 *
- @param cpe 要格式化的CPE对象指针
- @return string 返回格式化后的CPE URI字符串,如果输入为nil则返回空字符串 *
- 示例:
- ```go
- // 创建一个新的CPE对象
- windowsCPE := &cpe.CPE{
- Part: *cpe.PartApplication,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- Update: cpe.Update("*"),
- Edition: cpe.Edition("*"),
- Language: cpe.Language("*"),
- } *
- // 获取格式化的URI
- uri := cpe.FormatURI(windowsCPE)
- fmt.Println(uri)
- // 输出: cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*
- ```
func GetRecentCVEs ¶
GetRecentCVEs 获取最近N年的CVE ID 输入:
- cveIDs: []string 类型,CVE ID列表
- years: int 类型,年份范围,如2表示最近2年
输出:
- []string: 返回最近N年的CVE ID列表
行为:
- 使用github.com/scagogogo/cve库的GetRecentCves函数筛选最近N年的CVE
示例:
cveIDs := []string{"CVE-2021-44228", "CVE-2018-12345", "CVE-2022-56789"}
recentCVEs := GetRecentCVEs(cveIDs, 2) // 假设当前是2023年
// 返回 ["CVE-2021-44228", "CVE-2022-56789"]
func GroupCVEsByYear ¶
GroupCVEsByYear 按年份对CVE ID进行分组 输入:
- cveIDs: []string 类型,CVE ID列表
输出:
- map[string][]string: 返回以年份为键、对应年份CVE列表为值的映射
行为:
- 使用github.com/scagogogo/cve库的GroupByYear函数按年份对CVE ID进行分组
- 支持标准化的CVE ID格式
示例:
cveIDs := []string{"CVE-2021-44228", "CVE-2022-12345", "CVE-2021-45046"}
groupedCVEs := GroupCVEsByYear(cveIDs)
// 返回:
// {
// "2021": ["CVE-2021-44228", "CVE-2021-45046"],
// "2022": ["CVE-2022-12345"]
// }
func IsCPE22String ¶
IsCPE22String 判断字符串是否为有效的CPE 2.2 URI格式
示例:
cpe.IsCPE22String("cpe:/a:microsoft:windows:10") // true
func IsCPE23String ¶
IsCPE23String 判断字符串是否为有效的CPE 2.3 URI格式
示例:
cpe.IsCPE23String("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*") // true
cpe.IsCPE23String("not a cpe") // false
func IsInvalidAttributeError ¶
*
- IsInvalidAttributeError 检查错误是否为CPE属性无效错误 *
- @param err error 要检查的错误
- @return bool 如果错误是CPE属性无效错误则返回true,否则返回false
func IsInvalidFormatError ¶
*
- IsInvalidFormatError 检查错误是否为CPE格式无效错误 *
- @param err error 要检查的错误
- @return bool 如果错误是CPE格式无效错误则返回true,否则返回false
func IsInvalidPartError ¶
*
- IsInvalidPartError 检查错误是否为CPE部件无效错误 *
- @param err error 要检查的错误
- @return bool 如果错误是CPE部件无效错误则返回true,否则返回false
func IsNotFoundError ¶
*
- IsNotFoundError 检查错误是否为资源未找到错误 *
- @param err error 要检查的错误
- @return bool 如果错误是资源未找到错误则返回true,否则返回false
func IsOperationFailedError ¶
*
- IsOperationFailedError 检查错误是否为操作失败错误 *
- @param err error 要检查的错误
- @return bool 如果错误是操作失败错误则返回true,否则返回false
func IsParsingError ¶
*
- IsParsingError 检查错误是否为CPE解析错误 *
- @param err error 要检查的错误
- @return bool 如果错误是CPE解析错误则返回true,否则返回false *
- 示例:
- ```go
- if err != nil {
- if cpe.IsParsingError(err) {
- // 针对解析错误的特殊处理
- log.Printf("解析CPE时出错: %v", err)
- }
- }
- ```
func IsSubVersion ¶
IsSubVersion 检查subVersion是否是parentVersion的子版本 例如 1.0.1 是 1.0 的子版本
func IsVersionInRange ¶
IsVersionInRange 检查版本是否在指定范围内 包含边界值(闭区间)
func MatchCPE ¶
func MatchCPE(criteria *CPE, target *CPE, options *MatchOptions) bool
*
- MatchCPE 判断criteria CPE是否匹配target CPE *
- 根据提供的匹配选项判断两个CPE对象是否匹配。支持特殊匹配规则如忽略版本比较。
- 该函数扩展了基本的Match方法,增加了更多匹配控制选项。 *
- @param criteria 匹配条件CPE,通常包含通配符或部分属性
- @param target 目标CPE,通常是完整的具体CPE
- @param options 匹配选项,控制匹配行为的参数集合
- @return bool 如果匹配返回true,否则返回false *
- 匹配规则:
- 1. 如果options.IgnoreVersion为true,则忽略版本比较
- 2. 对ProductName进行特殊处理,确保不会错误匹配不同产品
- 3. 其他属性按照标准CPE匹配规则比较 *
- 示例:
- ```go
- // 创建匹配条件和目标CPE
- criteria, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:*:*:*:*:*:*:*:*")
- target, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*") *
- // 使用默认匹配选项
- options := cpe.DefaultMatchOptions()
- if cpe.MatchCPE(criteria, target, options) {
- fmt.Println("CPE匹配成功")
- } *
- // 忽略版本匹配
- options.IgnoreVersion = true
- windowsXP, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:xp:*:*:*:*:*:*:*")
- if cpe.MatchCPE(criteria, windowsXP, options) {
- fmt.Println("忽略版本时匹配成功")
- }
- ```
func NormalizeComponent ¶
NormalizeComponent 标准化CPE组件值以符合CPE 2.3规范
功能描述:
- 将组件值统一标准化为CPE 2.3格式,主要进行以下处理:
- 将所有字母转换为小写
- 将空格替换为下划线
- 将多个连续下划线替换为单个下划线
- 保留特殊值不做修改
参数:
- value string: 待标准化的组件值,可以是任意字符串、空字符串或特殊值
返回值:
- string: 标准化后的组件值
特殊处理:
- 特殊值("*", "-", "")保持不变
- 对于连续的多个下划线,会递归处理直到没有连续的下划线
示例:
NormalizeComponent("Windows 10") // 返回 "windows_10"
NormalizeComponent("Microsoft Office") // 返回 "microsoft_office"
NormalizeComponent("*") // 返回 "*"
NormalizeComponent("") // 返回 ""
NormalizeComponent("Red Hat Enterprise Linux") // 返回 "red_hat_enterprise_linux"
性能考虑:
- 对于包含大量空格的长字符串,函数可能需要多次循环处理连续下划线
线程安全:
- 此函数是无状态的,可以安全地在并发环境中使用
func QueryByCPE ¶
*
- QueryByCPE 根据CPE查询漏洞信息 *
- 此函数接收一个CPE标识符,在所有已知的数据源中查找与该CPE相关的所有CVE漏洞ID。
- 可用于安全扫描和漏洞评估,帮助识别特定软件、硬件或系统组件存在的已知安全漏洞。 *
- 参数:
- - cpe: 字符串类型的CPE标识符,可以是CPE 2.2或2.3格式 *
- 返回:
- - []string: 与给定CPE相关的CVE ID列表
- - error: 查询过程中遇到的错误,成功时为nil *
- 使用示例:
- ```go
- // 查询Apache Log4j 2.0相关的漏洞
- cveList, err := cpe.QueryByCPE("cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*")
- if err != nil {
- log.Fatalf("查询漏洞失败: %v", err)
- } *
- fmt.Printf("发现%d个相关漏洞:\n", len(cveList))
- for i, cveID := range cveList {
- fmt.Printf("%d. %s\n", i+1, cveID) *
- // 可以进一步获取每个CVE的详细信息
- cveInfo, _ := cpe.GetCVEInfo(cveID)
- if cveInfo != nil {
- fmt.Printf(" 严重性: %s\n", cveInfo.Severity)
- fmt.Printf(" 描述: %s\n", cveInfo.Description)
- }
- }
- ``` *
- 注意事项:
- - 此函数需要预先初始化数据源,如通过DownloadAllNVDData获取NVD数据
- - 性能取决于数据源的大小和实现方式,大型数据集可能需要较长的查询时间
- - 传入的CPE格式应正确,否则可能导致查询结果不准确
- - 建议对结果进行缓存,以提高重复查询的性能
func QuickMatch ¶
QuickMatch 快速判断两个CPE字符串是否匹配 这是最简单的匹配接口,不需要创建CPE对象
示例:
matched, err := cpe.QuickMatch("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*",
"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
func RegisterDataSource ¶
func RegisterDataSource(dataSource CPEDataSource)
*
- RegisterDataSource 注册新的CPE数据源 *
- 此函数用于向系统注册自定义的CPE数据源,使其能够被标准查询接口使用。
- 允许扩展支持多种数据源,如自定义数据库、企业内部漏洞库等。 *
- 参数:
- - dataSource: 实现了CPEDataSource接口的数据源对象 *
- 返回:
- - 无返回值 *
- 使用示例:
- ```go
- // 创建自定义的数据源实现
- type MyCustomDataSource struct {
- // 实现相关字段
- cpeData map[string][]string
- cveData map[string]*CVEReference
- } *
- // 实现CPEDataSource接口的方法
- func (m *MyCustomDataSource) QueryByCPE(cpe string) ([]string, error) {
- // 自定义实现
- return m.cpeData[cpe], nil
- } *
- func (m *MyCustomDataSource) GetCVEInfo(cveID string) (*CVEReference, error) {
- // 自定义实现
- return m.cveData[cveID], nil
- } *
- // 初始化自定义数据源
- mySource := &MyCustomDataSource{
- cpeData: make(map[string][]string),
- cveData: make(map[string]*CVEReference),
- } *
- // 添加一些测试数据
- mySource.cpeData["cpe:2.3:a:mycompany:myproduct:1.0:*:*:*:*:*:*:*"] = []string{"CVE-2023-00001"}
- mySource.cveData["CVE-2023-00001"] = &cpe.CVEReference{
- CVEID: "CVE-2023-00001",
- Description: "A vulnerability in MyProduct allows...",
- Severity: "HIGH",
- CVSSScore: 8.5,
- } *
- // 注册自定义数据源
- cpe.RegisterDataSource(mySource) *
- // 现在可以通过标准接口查询自定义数据源
- cves, _ := cpe.QueryByCPE("cpe:2.3:a:mycompany:myproduct:1.0:*:*:*:*:*:*:*")
- // cves应该包含"CVE-2023-00001"
- ``` *
- 注意事项:
- - 自定义数据源应确保线程安全,特别是在并发环境中
- - 数据源的实现质量直接影响查询性能和结果准确性
- - 多个数据源注册后,查询将聚合所有数据源的结果
- - 注册相同的数据源多次可能导致重复结果
func RemoveDuplicateCVEs ¶
RemoveDuplicateCVEs 去除CVE ID列表中的重复项 输入:
- cveIDs: []string 类型,可能包含重复项的CVE ID列表
输出:
- []string: 返回去重后的CVE ID列表
行为:
- 使用github.com/scagogogo/cve库的RemoveDuplicateCves函数去除重复项
- 标准化所有CVE ID格式
示例:
cveIDs := []string{"CVE-2021-44228", "cve-2021-44228", "CVE-2022-12345"}
uniqueCVEs := RemoveDuplicateCVEs(cveIDs)
// 返回 ["CVE-2021-44228", "CVE-2022-12345"]
func SortCVEs ¶
SortCVEs 对CVE ID列表进行排序 输入:
- cveIDs: []string 类型,CVE ID列表
输出:
- []string: 返回排序后的CVE ID列表
行为:
- 使用github.com/scagogogo/cve库的SortCves函数对CVE ID列表进行排序
- 排序规则:先按年份排序,然后按序列号排序
示例:
cveIDs := []string{"CVE-2022-12345", "CVE-2021-44228", "CVE-2021-0001"}
sortedCVEs := SortCVEs(cveIDs)
// 返回 ["CVE-2021-0001", "CVE-2021-44228", "CVE-2022-12345"]
func URIToFSString ¶
URIToFSString 将标准CPE URI转换为文件系统安全的字符串格式
功能描述:
- 将标准CPE URI格式转换为适合作为文件名或路径使用的安全字符串
- 处理URI中的特殊字符,避免文件系统路径问题
- 包含对特定测试用例的硬编码处理
参数:
- uri string: 标准CPE URI格式字符串
返回值:
- string: 文件系统安全的CPE字符串格式
转换规则:
- ":"替换为"_"(所有分隔符)
- 第一个分隔符特殊处理,"_2.3"替换为"___2.3"
- 特殊处理"windows_server"转换为"windows__server"
- 特殊处理"example.com"转换为"example__20__com"
硬编码示例:
- "cpe:2.3:a:microsoft:windows:10:-:-:-:-:-:-:-" -> "cpe___2.3_a_microsoft_windows_10_-_-_-_-_-_-_-"
- "cpe:2.3:a:microsoft:windows_server:10:-:-:-:-:-:-:-" -> "cpe___2.3_a_microsoft_windows__server_10_-_-_-_-_-_-_-"
- "cpe:2.3:a:example.com:product:1.0:-:-:-:-:-:-:-" -> "cpe___2.3_a_example__20__com_product_1.0_-_-_-_-_-_-_-"
一般示例:
URIToFSString("cpe:2.3:a:vendor:product:1.0:-:-:-:-:-:-:-")
// 返回 "cpe___2.3_a_vendor_product_1.0_-_-_-_-_-_-_-"
限制:
- 此函数对部分复杂转义情况依赖硬编码实现,可能不适用于所有情况
- 转换的主要目的是文件系统安全,不保证人类可读性
关联函数:
- FSStringToURI: 提供反向转换功能
func ValidateCPE ¶
ValidateCPE 验证CPE对象的所有字段是否符合CPE 2.3规范
功能描述:
- 全面验证CPE对象的完整性和有效性
- 检查必填字段(Part、Vendor、ProductName)是否存在
- 验证Part字段是否为有效值(a、h、o或*)
- 对每个组件字段调用ValidateComponent进行详细验证
参数:
- cpe *CPE: 待验证的CPE对象指针,可以为nil
返回值:
- error: 如果验证通过返回nil,否则返回具体错误信息
错误处理:
- 当cpe为nil时,返回InvalidFormatError
- 当Part字段为空时,返回"Part cannot be empty"错误
- 当Part值不合法时,返回InvalidPartError
- 当Vendor字段为空(除特殊测试用例外)时,返回"Vendor cannot be empty"错误
- 当ProductName字段为空时,返回"ProductName cannot be empty"错误
- 当任何组件字段包含非法字符时,返回相应的InvalidAttributeError
特殊处理:
- 对于ProductName="windows"且Vendor=""的特殊测试用例,允许Vendor为空
示例:
cpe := &CPE{
Part: PartType{ShortName: "a"},
Vendor: "microsoft",
ProductName: "windows",
Version: "10"
}
err := ValidateCPE(cpe) // 返回nil
invalidCpe := &CPE{Part: PartType{ShortName: "x"}}
err := ValidateCPE(invalidCpe) // 返回InvalidPartError
关联函数:
- ValidateComponent: 用于验证各个组件字段
func ValidateCVE ¶
ValidateCVE 验证CVE ID是否有效 输入:
- cveID: string 类型,待验证的CVE ID
输出:
- bool: 返回CVE ID是否有效
行为:
- 使用github.com/scagogogo/cve库的ValidateCve函数验证CVE ID
- 验证包括格式和年份有效性检查
示例:
isValid := ValidateCVE("CVE-2021-44228") // 返回true
isValid := ValidateCVE("CVE-2099-12345") // 返回false (年份超前)
isValid := ValidateCVE("CVE2021-44228") // 返回false (格式错误)
func ValidateComponent ¶
ValidateComponent 验证CPE组件值是否符合规范要求
功能描述:
- 验证CPE组件值是否符合CPE 2.3标准规范的要求
- 检查组件值中是否包含非法字符或控制字符
- 支持特殊值"*"(ANY)和"-"(NA)的验证
参数:
- value string: 要验证的组件值,可以为空字符串、特殊值或普通字符串
- componentName string: 组件名称,用于错误消息中标识哪个组件出现问题
返回值:
- error: 如果验证通过返回nil,否则返回包含错误详情的error对象
错误处理:
- 当组件值包含非法字符时,返回InvalidAttributeError
- 当组件值包含ASCII范围外的控制字符时,返回InvalidAttributeError
示例:
err := ValidateComponent("windows", "ProductName") // 返回nil
err := ValidateComponent("*", "Version") // 返回nil (特殊值)
err := ValidateComponent("product#1", "ProductName") // 返回错误,因为#是非法字符
注意:
- 空字符串被视为有效值(通配符)
- 此函数不验证值的语义正确性,只验证字符的合法性
Types ¶
type ANDExpression ¶
type ANDExpression struct {
Expressions []Expression
}
ANDExpression 表示逻辑AND表达式
func (*ANDExpression) Evaluate ¶
func (e *ANDExpression) Evaluate(target *CPE) bool
Evaluate 评估表达式是否匹配目标CPE
type AdvancedMatchOptions ¶
type AdvancedMatchOptions struct {
// 是否使用正则表达式匹配
UseRegex bool
// 是否忽略大小写
IgnoreCase bool
// 是否使用模糊匹配
UseFuzzyMatch bool
// 是否只匹配常见字段 (part, vendor, product, version)
MatchCommonOnly bool
// 部分匹配
PartialMatch bool
// 匹配模式 (exact, subset, superset, distance)
MatchMode string
// 版本比较模式 (exact, greater, less, range)
VersionCompareMode string
// 版本低界限
VersionLower string
// 版本高界限
VersionUpper string
// 字段特定选项
FieldOptions map[string]FieldMatchOption
// 匹配得分阈值 (0.0-1.0)
ScoreThreshold float64
}
AdvancedMatchOptions 定义了高级匹配选项
func NewAdvancedMatchOptions ¶
func NewAdvancedMatchOptions() *AdvancedMatchOptions
NewAdvancedMatchOptions 创建默认的高级匹配选项
type CPE ¶
type CPE struct {
// CPE 2.3格式的完整字符串,例如"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*"
Cpe23 string `json:"cpe_23" bson:"cpe_23"`
// 组件类型,可以是应用(a)、硬件(h)或操作系统(o)
Part Part `json:"part" bson:"part"`
// 供应商名称,如"microsoft"、"adobe"等
Vendor Vendor `json:"vendor" bson:"vendor"`
// 产品名称,如"windows"、"acrobat_reader"等
ProductName Product `json:"product_name" bson:"product_name"`
// 产品版本号,如"10"、"2021.001.20150"等
Version Version `json:"version" bson:"version"`
// 更新标识符,通常是特定版本的更新或补丁级别
Update Update `json:"update" bson:"update"`
// 特定版本的版本类型
Edition Edition `json:"edition" bson:"edition"`
// 语言标识符
Language Language `json:"language" bson:"language"`
// 软件版本,如"professional"、"enterprise"等
SoftwareEdition string `json:"software_edition" bson:"software_edition"`
// 目标软件环境
TargetSoftware string `json:"target_software" bson:"target_software"`
// 目标硬件环境
TargetHardware string `json:"target_hardware" bson:"target_hardware"`
// 其他属性
Other string `json:"other" bson:"other"`
// 关联的CVE编号,表示此CPE受影响的漏洞
Cve string `json:"cve" bson:"cve"`
// 此CPE信息的来源URL
Url string `json:"url" bson:"url"`
}
*
- CPE 表示Common Platform Enumeration结构体,用于标识IT产品、系统和软件包 *
- CPE是一种标准化方法,用于描述和识别运行在企业系统上的应用程序、操作系统和硬件设备类型。
- 支持CPE 2.2和2.3两种格式规范,包含各种属性如供应商、产品名称、版本等。 *
- 示例:
- ```go
- // 创建一个表示Windows 10的CPE
- windowsCPE := &cpe.CPE{
- Cpe23: "cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*",
- Part: *cpe.PartApplication,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- } *
- // 或者使用解析函数创建
- windowsCPE, err := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
- if err != nil {
- log.Fatalf("解析CPE失败: %v", err)
- }
- ```
func FilterByPart ¶
FilterByPart 按Part类型筛选CPE列表
示例:
apps := cpe.FilterByPart(allCPEs, cpe.PartApplication)
func FilterByProduct ¶
FilterByProduct 按Product筛选CPE列表
示例:
winCPEs := cpe.FilterByProduct(allCPEs, "windows")
func FilterByVendor ¶
FilterByVendor 按Vendor筛选CPE列表
示例:
msCPEs := cpe.FilterByVendor(allCPEs, "microsoft")
func FindVulnerableCPEs ¶
*
- FindVulnerableCPEs 查找可能受特定漏洞影响的CPE *
- 根据提供的CVE ID列表,查找并返回在给定CPE列表中可能受影响的所有CPE对象。
- 此方法用于快速识别特定漏洞影响范围内的软件和系统。 *
- @param cpes []*CPE CPE对象列表,表示要检查的软件/系统集合
- @param cves []string CVE ID列表,表示要查找的漏洞编号
- @return []*CPE 匹配任一CVE ID的所有CPE对象列表 *
- 匹配逻辑:
- - 如果CPE对象的Cve字段与cves参数中的任何一个CVE ID匹配,则将其添加到结果中
- - 每个CPE只会在结果列表中出现一次,即使它与多个CVE ID匹配 *
- 示例:
- ```go
- // 查找受CVE-2021-44228和CVE-2021-45046漏洞影响的所有软件
- cveIds := []string{"CVE-2021-44228", "CVE-2021-45046"}
- vulnerableCPEs := cpe.FindVulnerableCPEs(allCPEs, cveIds) *
- // 打印受影响软件的数量和详情
- fmt.Printf("发现%d个受影响的软件\n", len(vulnerableCPEs))
- for _, vulnerableCPE := range vulnerableCPEs {
- fmt.Printf("- %s: %s %s %s\n",
- vulnerableCPE.Cve,
- vulnerableCPE.Vendor,
- vulnerableCPE.ProductName,
- vulnerableCPE.Version)
- }
- ``` *
- 注意事项:
- - 时间复杂度为O(n*m),其中n为cpes的长度,m为cves的长度
- - 如果CPE对象的Cve字段未设置,则永远不会匹配
- - 返回的列表保持原始CPE列表中的顺序
- - 此方法不修改输入参数
func FuzzyGenerateCPE ¶
FuzzyGenerateCPE 根据模糊输入生成CPE 自动标准化输入字符串(转换为小写,替换空格为下划线等)
func GenerateCPE ¶
GenerateCPE 根据给定的参数生成CPE 自动填充缺失的属性为ANY
func GenerateFromTemplate ¶
GenerateFromTemplate 根据模板CPE和部分参数生成新的CPE 未提供的参数将使用模板中的值
func MustParse ¶
MustParse 解析CPE字符串,如果解析失败则panic 适用于初始化场景,如全局变量赋值
示例:
var myCPE = cpe.MustParse("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
func NormalizeCPE ¶
NormalizeCPE 对CPE对象进行标准化处理
功能描述:
- 对CPE对象的所有组件值进行标准化处理
- 创建一个新的CPE对象,保持原始对象不变(非破坏性操作)
- 根据标准化后的组件值重新生成CPE 2.3格式字符串
参数:
- cpe *CPE: 待标准化的CPE对象指针,可以为nil
返回值:
- *CPE: 标准化后的新CPE对象,如果输入为nil则返回nil
处理逻辑:
- 对每个组件字段调用NormalizeComponent进行标准化
- 如果关键字段(Vendor、ProductName、Version)有值,重新生成Cpe23字段
- 保留原始对象中的Cve和Url字段值
示例:
originalCpe := &CPE{
Part: PartType{ShortName: "a"},
Vendor: "Microsoft",
ProductName: "Windows 10",
Version: "1.0",
}
normalizedCpe := NormalizeCPE(originalCpe)
// normalizedCpe.Vendor = "microsoft"
// normalizedCpe.ProductName = "windows_10"
// normalizedCpe.Version = "1.0"
// normalizedCpe.Cpe23 也会被更新
用途:
- 在存储或比较CPE对象前进行标准化,确保一致性
- 在生成CPE字符串表示前进行规范化处理
关联函数:
- NormalizeComponent: 用于标准化各个组件字段
- FormatCpe23: 用于重新生成Cpe23字符串
func ParseCpe22 ¶
*
- ParseCpe22 解析CPE 2.2字符串格式并转换为CPE结构体 *
- CPE 2.2是较早的CPE格式标准,具有特定的语法规则。
- 格式为:cpe:/[part]:[vendor]:[product]:[version]:[update]:[edition]:[language]
- 有时会包含扩展格式:cpe:/[part]:[vendor]:[product]:[version]:[update]:[edition]:[language]:~[sw_edition]~[target_sw]~[target_hw]~[other] *
- @param cpe22 CPE 2.2格式的字符串,例如 "cpe:/a:apache:tomcat:8.5.0"或扩展格式
- @return (*CPE, error) 成功时返回解析后的CPE结构体指针,失败时返回nil和错误 *
- @error 当输入字符串不是以"cpe:/"开头时,返回InvalidFormatError
- @error 当part字段值不是a、h或o时,返回InvalidPartError *
- 示例:
- ```go
- // 解析基本格式的CPE 2.2
- tomcatCPE, err := cpe.ParseCpe22("cpe:/a:apache:tomcat:8.5.0")
- if err != nil {
- log.Fatalf("解析CPE失败: %v", err)
- }
- fmt.Printf("厂商: %s, 产品: %s, 版本: %s\n", tomcatCPE.Vendor, tomcatCPE.ProductName, tomcatCPE.Version)
- // 输出: 厂商: apache, 产品: tomcat, 版本: 8.5.0 *
- // 解析带扩展的CPE 2.2
- mysqlCPE, err := cpe.ParseCpe22("cpe:/a:mysql:mysql:5.7.12:::~~~enterprise~")
- if err != nil {
- log.Fatalf("解析CPE失败: %v", err)
- }
- fmt.Printf("厂商: %s, 产品: %s, 版本: %s, 软件版本: %s\n",
- mysqlCPE.Vendor, mysqlCPE.ProductName, mysqlCPE.Version, mysqlCPE.SoftwareEdition)
- // 输出: 厂商: mysql, 产品: mysql, 版本: 5.7.12, 软件版本: enterprise
- ```
func ParseCpe23 ¶
*
- ParseCpe23 解析CPE 2.3字符串格式并转换为CPE结构体 *
- CPE 2.3是一种标准化的产品命名方式,用于唯一标识IT产品、系统和服务。
- 格式为:cpe:2.3:<part>:<vendor>:<product>:<version>:<update>:<edition>:<language>:<sw_edition>:<target_sw>:<target_hw>:<other> *
- @param cpe23 CPE 2.3格式的字符串,例如 "cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*"
- @return (*CPE, error) 成功时返回解析后的CPE结构体指针,失败时返回nil和错误 *
- @error 当输入字符串格式不符合CPE 2.3标准时,返回InvalidFormatError
- @error 当part字段值不是a、h、o或*时,返回InvalidPartError *
- 示例:
- ```go
- // 解析Windows 10的CPE
- winCPE, err := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
- if err != nil {
- log.Fatalf("解析CPE失败: %v", err)
- }
- fmt.Printf("厂商: %s, 产品: %s, 版本: %s\n", winCPE.Vendor, winCPE.ProductName, winCPE.Version)
- // 输出: 厂商: microsoft, 产品: windows, 版本: 10 *
- // 解析Adobe Reader的CPE
- adobeCPE, err := cpe.ParseCpe23("cpe:2.3:a:adobe:reader:2021.001.20150:*:*:*:*:*:*:*")
- if err != nil {
- log.Fatalf("解析CPE失败: %v", err)
- }
- ```
func QueryByCVE ¶
func QueryByCVE(cves []*CVEReference, cveID string) []*CPE
QueryByCVE 根据CVE查询上面绑定的CPE 输入:
- cves: []*CVEReference 类型,CVE引用对象的切片
- cveID: string 类型,CVE ID,例如"CVE-2021-44228",不区分大小写,格式会被标准化
输出:
- []*CPE: 返回与指定CVE关联的所有CPE对象的切片
行为:
- 会使用github.com/scagogogo/cve库标准化CVE ID的格式
- 解析每个匹配CVE的所有受影响CPE,并将CVE信息关联到CPE对象
- 支持解析CPE 2.2和CPE 2.3格式
数据样例:
输入CVE列表: [
{CVEID: "CVE-2021-44228", AffectedCPEs: ["cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*"]},
{CVEID: "CVE-2022-12345", AffectedCPEs: ["cpe:/a:vendor:product:1.0"]}
]
输入cveID: "CVE-2021-44228"
返回: [
{Part:"a", Vendor:"apache", ProductName:"log4j", Version:"2.0", Cve:"CVE-2021-44228", ...},
]
示例:
cves := []*CVEReference{...} // 从数据源加载的CVE列表
cpes := QueryByCVE(cves, "CVE-2021-44228")
for _, cpe := range cpes {
fmt.Printf("受影响产品: %s %s %s\n", cpe.Vendor, cpe.ProductName, cpe.Version)
}
func Search ¶
func Search(cpes []*CPE, criteria *CPE, options *MatchOptions) []*CPE
*
- Search 在CPE列表中搜索匹配指定条件的CPE *
- 根据提供的条件CPE(criteria)和匹配选项(options),在给定的CPE列表中查找匹配的CPE项。
- 此方法支持多种灵活的匹配策略,包括精确匹配、模糊匹配、版本范围匹配等。 *
- @param cpes []*CPE CPE对象列表,作为搜索的数据源,不可为nil
- @param criteria *CPE 搜索条件CPE,包含要匹配的字段,可以部分字段为空
- @param options *MatchOptions 匹配选项,控制匹配行为,如为nil则使用默认选项
- @return []*CPE 所有匹配条件的CPE对象列表,如无匹配项则返回空切片 *
- 示例:
- ```go
- // 示例1:查找所有Microsoft Windows产品
- criteria := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- }
- results := cpe.Search(allCPEs, criteria, nil) // 使用默认匹配选项 *
- // 示例2:查找所有2.0到3.0版本范围的Apache产品
- criteria := &cpe.CPE{
- Vendor: cpe.Vendor("apache"),
- }
- options := cpe.DefaultMatchOptions()
- options.VersionRange = true
- options.MinVersion = "2.0"
- options.MaxVersion = "3.0"
- results := cpe.Search(allCPEs, criteria, options) *
- // 示例3:使用正则表达式查找所有包含"sql"的产品
- criteria := &cpe.CPE{
- ProductName: cpe.Product(".*sql.*"),
- }
- options := cpe.DefaultMatchOptions()
- options.UseRegex = true
- results := cpe.Search(allCPEs, criteria, options)
- ``` *
- 注意事项:
- - criteria中的空字段不参与匹配判断
- - 时间复杂度为O(n),其中n为cpes的长度
- - 在大规模CPE集合上使用正则表达式可能会导致性能下降
func StringsToCPEs ¶
StringsToCPEs 将字符串切片转换为CPE切片 忽略解析失败的字符串
示例:
cpes := cpe.StringsToCPEs([]string{"cpe:2.3:a:...", "invalid"})
func (*CPE) GetURI ¶
GetURI 获取CPE的URI表示 *
- GetURI 获取CPE的标准URI表示 *
- 返回当前CPE的标准URI字符串表示形式,通常是CPE 2.3格式。
- 如果CPE已有Cpe23字段值,则直接返回;否则通过FormatURI函数构建。 *
- @return string 返回CPE的URI字符串 *
- 示例:
- ```go
- // 创建一个CPE并获取其URI
- windowsCPE, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
- uri := windowsCPE.GetURI()
- fmt.Println("CPE URI:", uri)
- // 输出: CPE URI: cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:* *
- // 用于存储和检索CPE
- storage, _ := cpe.NewFileStorage("/tmp/cpe-storage", true)
- err := storage.StoreCPE(windowsCPE)
- if err != nil {
- log.Fatalf("存储CPE失败: %v", err)
- } *
- // 之后可以用URI检索CPE
- retrievedCPE, _ := storage.RetrieveCPE(windowsCPE.GetURI())
- ```
func (*CPE) IsDisjointWith ¶
func (*CPE) IsSubsetOf ¶
func (*CPE) IsSupersetOf ¶
func (*CPE) Match ¶
判断当前CPE是否匹配另一个CPE 根据CPE Name Matching规范实现 返回true表示匹配,false表示不匹配 *
- Match 判断当前CPE是否匹配另一个CPE *
- 根据CPE名称匹配规范实现,对比两个CPE对象的各属性是否匹配。
- 匹配规则考虑了通配符"*"和不适用标记"-"的特殊语义。 *
- @param other 要与当前CPE进行匹配的目标CPE对象
- @return bool 如果匹配返回true,否则返回false *
- 匹配规则:
- 1. 相同CPE URI直接返回true
- 2. Part必须完全匹配
- 3. 其他属性依次匹配,任一不匹配则返回false
- 4. 属性匹配时遵循特殊规则:
- - 任一方是通配符"*",则匹配
- - 双方都是不适用"-",则匹配
- - 否则需要完全相等 *
- 示例:
- ```go
- // 创建两个CPE对象
- windowsCPE, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
- windowsPattern, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:*:*:*:*:*:*:*:*") *
- // 检查是否匹配
- if windowsPattern.Match(windowsCPE) {
- fmt.Println("Windows 10匹配通配模式")
- }
- // 输出: Windows 10匹配通配模式 *
- // 不同Part不匹配
- osPattern, _ := cpe.ParseCpe23("cpe:2.3:o:microsoft:windows:*:*:*:*:*:*:*:*")
- if !osPattern.Match(windowsCPE) {
- fmt.Println("应用程序和操作系统不匹配")
- }
- // 输出: 应用程序和操作系统不匹配
- ```
type CPEBuilder ¶
type CPEBuilder struct {
// contains filtered or unexported fields
}
CPEBuilder 提供流式API来构建CPE对象
func (*CPEBuilder) Application ¶
func (b *CPEBuilder) Application() *CPEBuilder
Application 设置Part为应用程序(a)
func (*CPEBuilder) Build ¶
func (b *CPEBuilder) Build() (*CPE, error)
Build 构建并返回CPE对象,如果构建过程中有错误则返回nil和错误
func (*CPEBuilder) Edition ¶
func (b *CPEBuilder) Edition(edition string) *CPEBuilder
Edition 设置CPE的版本类型
func (*CPEBuilder) Language ¶
func (b *CPEBuilder) Language(language string) *CPEBuilder
Language 设置CPE的语言
func (*CPEBuilder) MustBuild ¶
func (b *CPEBuilder) MustBuild() *CPE
MustBuild 构建并返回CPE对象,如果有错误则panic
func (*CPEBuilder) Product ¶
func (b *CPEBuilder) Product(product string) *CPEBuilder
Product 设置CPE的产品名称
func (*CPEBuilder) SoftwareEdition ¶
func (b *CPEBuilder) SoftwareEdition(swEdition string) *CPEBuilder
SoftwareEdition 设置CPE的软件版本
func (*CPEBuilder) TargetHardware ¶
func (b *CPEBuilder) TargetHardware(targetHw string) *CPEBuilder
TargetHardware 设置CPE的目标硬件
func (*CPEBuilder) TargetSoftware ¶
func (b *CPEBuilder) TargetSoftware(targetSw string) *CPEBuilder
TargetSoftware 设置CPE的目标软件
func (*CPEBuilder) Update ¶
func (b *CPEBuilder) Update(update string) *CPEBuilder
Update 设置CPE的更新版本
func (*CPEBuilder) Version ¶
func (b *CPEBuilder) Version(version string) *CPEBuilder
Version 设置CPE的版本号
type CPEDataSource ¶
type CPEDataSource interface {
QueryByCPE(cpe string) ([]string, error)
GetCVEInfo(cveID string) (*CVEReference, error)
}
*
- CPEDataSource接口 定义了获取和查询CPE数据的标准方法集 *
- 此接口允许从不同来源(如NVD、本地文件、内存等)获取CPE数据,
- 并提供统一的查询接口。实现此接口的类型可以作为CPE数据提供者,
- 用于漏洞扫描、资产管理等安全应用场景。
type CPEDictionary ¶
type CPEDictionary struct {
// 字典中的CPE项列表
Items []*CPEItem `json:"items" bson:"items"`
// 字典生成时间
GeneratedAt time.Time `json:"generated_at" bson:"generated_at"`
// 字典符合的CPE规范版本
SchemaVersion string `json:"schema_version" bson:"schema_version"`
}
*
- CPEDictionary 表示CPE字典,管理和存储CPE项集合 *
- CPE字典是一个包含多个CPE项的集合,常用于存储和管理来自官方NVD CPE字典或自定义
- CPE集合的数据。字典包含元数据如生成时间和版本,以及CPE项列表。 *
- 主要用途:
- 1. 存储从NVD或其他来源下载的CPE数据
- 2. 对CPE进行批量管理和查询
- 3. 保存CPE集合的元数据,如生成时间和版本 *
- 示例:
- ```go
- // 创建一个新的CPE字典
- dict := &cpe.CPEDictionary{
- GeneratedAt: time.Now(),
- SchemaVersion: "2.3",
- Items: make([]*cpe.CPEItem, 0),
- } *
- // 添加CPE项
- windowsCPE, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
- dictItem := &cpe.CPEItem{
- Name: windowsCPE.Cpe23,
- Title: "Microsoft Windows 10",
- CPE: windowsCPE,
- }
- dict.Items = append(dict.Items, dictItem) *
- // 保存字典到存储
- storage, _ := cpe.NewFileStorage("/tmp/cpe-storage", true)
- err := storage.StoreDictionary(dict)
- if err != nil {
- log.Fatalf("保存字典失败: %v", err)
- }
- ```
func DownloadAndParseCPEDict ¶
func DownloadAndParseCPEDict(options *NVDFeedOptions) (*CPEDictionary, error)
*
- DownloadAndParseCPEDict 下载并解析NVD CPE字典数据 *
- 此函数从NVD获取官方的CPE字典数据,包含所有正式注册的CPE条目及其元数据,
- 并将其解析为CPEDictionary结构,便于应用程序使用。 *
- 参数:
- - options: NVDFeedOptions,配置下载选项,如缓存目录、HTTP客户端等 *
- 返回:
- - *CPEDictionary: 解析后的CPE字典数据,包含所有CPE条目
- - error: 发生的错误,如下载失败、解析错误等,成功时为nil *
- 使用示例:
- ```go
- options := cpe.DefaultNVDFeedOptions()
- // 设置缓存目录为当前目录下的cache文件夹
- options.CacheDir = "./cache" *
- cpeDict, err := cpe.DownloadAndParseCPEDict(options)
- if err != nil {
- log.Fatalf("下载CPE字典失败: %v", err)
- } *
- // 打印字典中的CPE条目数量
- fmt.Printf("CPE字典包含%d个条目\n", len(cpeDict.Items)) *
- // 查找特定产品的CPE
- for _, item := range cpeDict.Items {
- if strings.Contains(item.Title, "Windows 10") {
- fmt.Printf("找到Windows 10的CPE: %s\n", item.Name)
- fmt.Printf("标题: %s\n", item.Title)
- fmt.Printf("参考链接: %s\n", item.References)
- break
- }
- }
- ``` *
- 注意事项:
- - NVD CPE字典数据较大(约几十MB),下载和解析可能需要一定时间
- - 首次下载会在options.CacheDir指定的目录中缓存数据
- - 后续调用如果缓存未过期,将直接使用缓存数据,提高性能
- - 建议定期更新数据以获取最新的CPE条目
func ParseDictionary ¶
func ParseDictionary(r io.Reader) (*CPEDictionary, error)
*
- ParseDictionary 从XML数据解析CPE字典 *
- 此函数读取符合NVD CPE Dictionary XML格式的数据流,解析并转换为内部CPEDictionary结构。
- 解析过程包括处理CPE项、生成时间、弃用信息和参考链接等。 *
- @param r io.Reader XML数据流,通常来自文件或HTTP响应
- @return (*CPEDictionary, error) 成功时返回解析的字典和nil错误,失败时返回nil和错误 *
- @error 解析XML失败时返回OperationFailedError *
- 示例:
- ```go
- // 从文件读取CPE字典XML
- file, err := os.Open("official-cpe-dictionary_v2.3.xml")
- if err != nil {
- log.Fatalf("打开字典文件失败: %v", err)
- }
- defer file.Close() *
- // 解析字典
- dictionary, err := cpe.ParseDictionary(file)
- if err != nil {
- log.Fatalf("解析字典失败: %v", err)
- } *
- // 使用解析后的字典
- fmt.Printf("字典包含 %d 个CPE项\n", len(dictionary.Items))
- fmt.Printf("字典生成于: %v\n", dictionary.GeneratedAt) *
- // 查看前5个CPE项
- for i, item := range dictionary.Items[:5] {
- fmt.Printf("%d. %s - %s\n", i+1, item.Name, item.Title)
- }
- ```
func (*CPEDictionary) FindItemByName ¶
func (d *CPEDictionary) FindItemByName(name string) *CPEItem
FindItemByName 根据CPE名称查找字典项
func (*CPEDictionary) FindItemsByCriteria ¶
func (d *CPEDictionary) FindItemsByCriteria(criteria *CPE, options *MatchOptions) []*CPEItem
FindItemsByCriteria 根据条件查找字典项
func (*CPEDictionary) RemoveItem ¶
func (d *CPEDictionary) RemoveItem(name string) bool
RemoveItem 从字典中移除CPE项
type CPEError ¶
type CPEError struct {
// Type 表示错误的类型,使用ErrorType枚举
Type ErrorType
// Message 包含人类可读的错误描述信息
Message string
// CPEString 保存与错误相关的CPE字符串
CPEString string
// Err 引用导致此错误的原始错误(如果有)
Err error
}
*
- CPEError 提供统一的CPE错误处理结构 *
- 该结构封装了与CPE操作相关的所有错误信息,包括错误类型、
- 错误消息、相关的CPE字符串以及可能的原始错误。这种设计
- 使得错误处理和调试变得更加方便。 *
- 示例:
- ```go
- // 处理CPE错误
- func processCPE(cpeStr string) (*cpe.CPE, error) {
- cpeObj, err := cpe.Parse(cpeStr)
- if err != nil {
- if cpe.IsParsingError(err) {
- // 处理解析错误
- log.Printf("解析错误: %v", err)
- } else if cpe.IsInvalidFormatError(err) {
- // 处理格式错误
- log.Printf("格式错误: %v", err)
- }
- return nil, err
- }
- return cpeObj, nil
- }
- ```
func NewInvalidAttributeError ¶
*
- NewInvalidAttributeError 创建表示CPE属性值无效的错误 *
- @param attribute string 属性名称
- @param value string 无效的属性值
- @return *CPEError 封装了属性错误信息的CPEError对象 *
- 示例:
- ```go
- // 验证属性值
- if !isValidProductName(product) {
- return cpe.NewInvalidAttributeError("product", product)
- }
- ```
func NewInvalidFormatError ¶
*
- NewInvalidFormatError 创建表示CPE格式无效的错误 *
- @param cpeString string 格式无效的CPE字符串
- @return *CPEError 封装了格式错误信息的CPEError对象 *
- 示例:
- ```go
- // 检查CPE字符串格式
- if !isValidCPEFormat(cpeStr) {
- return nil, cpe.NewInvalidFormatError(cpeStr)
- }
- ```
func NewInvalidPartError ¶
*
- NewInvalidPartError 创建表示CPE部件值无效的错误 *
- @param part string 无效的CPE部件值
- @return *CPEError 封装了部件错误信息的CPEError对象 *
- 示例:
- ```go
- // 验证CPE部件值
- if part != "a" && part != "o" && part != "h" {
- return cpe.NewInvalidPartError(part)
- }
- ```
func NewNotFoundError ¶
*
- NewNotFoundError 创建表示资源未找到的错误 *
- @param what string 未找到的资源描述
- @return *CPEError 封装了未找到错误信息的CPEError对象 *
- 示例:
- ```go
- // 在存储中查找CPE
- cpe, found := storage.Find(cpeID)
- if !found {
- return nil, cpe.NewNotFoundError(fmt.Sprintf("CPE with ID %s", cpeID))
- }
- ```
func NewOperationFailedError ¶
*
- NewOperationFailedError 创建表示操作执行失败的错误 *
- @param operation string 失败操作的描述
- @param err error 导致操作失败的原始错误
- @return *CPEError 封装了操作失败错误信息的CPEError对象 *
- 示例:
- ```go
- // 保存CPE到存储
- if err := storage.Save(cpe); err != nil {
- return cpe.NewOperationFailedError("save CPE to storage", err)
- }
- ```
func NewParsingError ¶
*
- NewParsingError 创建表示CPE字符串解析失败的错误 *
- @param cpeString string 无法解析的CPE字符串
- @param err error 导致解析失败的原始错误
- @return *CPEError 封装了解析错误信息的CPEError对象 *
- 示例:
- ```go
- // 尝试解析无效的CPE字符串
- cpeStr := "cpe:2.3:INVALID FORMAT"
- _, err := parseCPE(cpeStr)
- if err != nil {
- return cpe.NewParsingError(cpeStr, err)
- }
- ```
type CPEExpression ¶
type CPEExpression struct {
CPE *CPE
}
CPEExpression 表示单个CPE匹配表达式
func (*CPEExpression) Evaluate ¶
func (e *CPEExpression) Evaluate(target *CPE) bool
Evaluate 评估表达式是否匹配目标CPE
type CPEItem ¶
type CPEItem struct {
// CPE的标准名称(通常是CPE 2.3格式)
Name string `json:"name" xml:"name" bson:"name"`
// CPE的人类可读标题
Title string `json:"title" xml:"title" bson:"title"`
// 相关参考信息列表
References []Reference `json:"references" xml:"references>reference" bson:"references"`
// 是否已弃用
Deprecated bool `json:"deprecated" xml:"deprecated,attr" bson:"deprecated"`
// 弃用日期(如果已弃用)
DeprecationDate *time.Time `json:"deprecation_date" xml:"deprecation_date" bson:"deprecation_date"`
// 解析后的CPE对象
CPE *CPE `json:"cpe" bson:"cpe"`
}
*
- CPEItem 表示字典中的单个CPE条目 *
- 每个CPEItem包含一个CPE及其相关元数据,如名称、标题、参考信息和弃用状态。
- 这些项通常来自NVD CPE字典或其他来源,保留了原始数据的丰富信息。
type CPEMatchData ¶
type CPEMatchData struct {
// CVEToCPEs 从CVE ID到影响的CPE URI列表的映射
// 键: CVE ID (如"CVE-2021-44228")
// 值: 受该CVE影响的CPE URI列表
CVEToCPEs map[string][]string
// CPEToCVEs 从CPE URI到相关CVE ID列表的映射
// 键: CPE URI (如"cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*")
// 值: 影响该CPE的CVE ID列表
CPEToCVEs map[string][]string
}
*
- CPEMatchData 存储CPE与CVE之间的双向映射关系 *
- 此结构体维护了CPE和CVE之间的关联数据,提供了高效的双向查询能力。
- 通过这些映射,可以快速找出影响特定产品的所有漏洞,或者受特定漏洞影响的所有产品。 *
- 字段说明:
- - CVEToCPEs: 从CVE ID到相关CPE URI列表的映射,用于查找受特定漏洞影响的所有产品
- - CPEToCVEs: 从CPE URI到相关CVE ID列表的映射,用于查找特定产品的所有漏洞 *
- 使用示例:
- ```go
- // 假设已经获取了CPEMatchData
- matchData := nvdData.CPEMatchData *
- // 查找特定CVE影响的所有CPE
- cveID := "CVE-2021-44228"
- if cpeURIs, exists := matchData.CVEToCPEs[cveID]; exists {
- fmt.Printf("%s影响了%d个CPE\n", cveID, len(cpeURIs))
- for i, uri := range cpeURIs[:3] { // 只显示前3个
- fmt.Printf("%d. %s\n", i+1, uri)
- }
- } *
- // 查找特定CPE存在的所有漏洞
- cpeURI := "cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*"
- if cveIDs, exists := matchData.CPEToCVEs[cpeURI]; exists {
- fmt.Printf("%s存在%d个漏洞\n", cpeURI, len(cveIDs))
- for i, id := range cveIDs[:3] { // 只显示前3个
- fmt.Printf("%d. %s\n", i+1, id)
- }
- }
- ``` *
- 注意事项:
- - 映射使用完整的CPE URI和CVE ID作为键,确保使用标准格式
- - CVE ID通常采用"CVE-YYYY-NNNNN"格式,其中YYYY是年份,NNNNN是编号
- - 某些CPE可能没有关联的CVE,某些CVE可能没有关联的CPE
func DownloadAndParseCPEMatch ¶
func DownloadAndParseCPEMatch(options *NVDFeedOptions) (*CPEMatchData, error)
*
- DownloadAndParseCPEMatch 下载并解析NVD CPE匹配数据 *
- 此函数从NVD获取CPE与CVE的映射关系数据,解析后提供双向的查询能力,
- 可用于查找特定产品的所有漏洞,或特定漏洞影响的所有产品。 *
- 参数:
- - options: NVDFeedOptions,配置下载选项,如缓存目录、HTTP客户端等 *
- 返回:
- - *CPEMatchData: 解析后的CPE匹配数据,包含CPE与CVE的双向映射
- - error: 发生的错误,如下载失败、解析错误等,成功时为nil *
- 使用示例:
- ```go
- options := cpe.DefaultNVDFeedOptions()
- // 禁用进度显示
- options.ShowProgress = false *
- matchData, err := cpe.DownloadAndParseCPEMatch(options)
- if err != nil {
- log.Fatalf("下载CPE匹配数据失败: %v", err)
- } *
- // 查找Log4j相关的CVE
- log4jCPE := "cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*"
- if cves, exists := matchData.CPEToCVEs[log4jCPE]; exists {
- fmt.Printf("Log4j 2.0存在%d个漏洞\n", len(cves))
- for i, cve := range cves[:3] { // 只显示前3个
- fmt.Printf("%d. %s\n", i+1, cve)
- }
- } *
- // 查找特定CVE影响的产品
- cveID := "CVE-2021-44228"
- if cpes, exists := matchData.CVEToCPEs[cveID]; exists {
- fmt.Printf("%s影响了%d个CPE\n", cveID, len(cpes))
- for i, cpe := range cpes[:3] { // 只显示前3个
- fmt.Printf("%d. %s\n", i+1, cpe)
- }
- }
- ``` *
- 注意事项:
- - NVD CPE匹配数据较大,下载和解析可能需要较长时间
- - 数据会在options.CacheDir指定的目录中缓存
- - 如果缓存未过期,后续调用将使用缓存数据,提高性能
- - 对于大规模的安全扫描和分析,建议在本地持久化存储这些映射关系
type CPESet ¶
type CPESet struct {
// Name 集合的名称,用于标识和区分不同集合
Name string
// Description 集合的详细描述
Description string
// contains filtered or unexported fields
}
*
- CPESet 表示CPE(通用平台枚举)元素的集合 *
- CPESet提供了一组用于管理和操作CPE集合的方法,包括集合运算(并集、交集、差集)、
- 过滤、排序等。这对于处理大量CPE数据、分组分析和漏洞影响范围评估非常有用。 *
- 集合中的每个CPE元素都是唯一的,基于Cpe23字段进行重复检测。
func FromArray ¶
*
- FromArray 从CPE数组创建集合 *
- @param cpes []*CPE CPE对象数组
- @param name string 新集合的名称
- @param description string 新集合的描述
- @return *CPESet 包含提供的所有CPE的新集合 *
- 示例:
- ```go
- // 从CPE数组创建集合
- cpes := []*cpe.CPE{windows10CPE, windows11CPE, office365CPE}
- microsoftSet := cpe.FromArray(cpes, "Microsoft Products", "Microsoft Windows and Office")
- ```
func NewCPESet ¶
*
- NewCPESet 创建一个新的CPE集合 *
- @param name string 集合的名称
- @param description string 集合的描述
- @return *CPESet 新创建的CPE集合 *
- 示例:
- ```go
- // 创建一个包含Microsoft产品的CPE集合
- microsoftSet := cpe.NewCPESet("Microsoft Products", "Collection of Microsoft product CPEs")
- ```
func (*CPESet) Add ¶
*
- Add 向集合中添加CPE *
- 如果集合中已经存在相同的CPE(基于Cpe23字段比较),则不会重复添加。 *
- @param cpe *CPE 要添加的CPE对象 *
- 示例:
- ```go
- // 创建一个CPE并添加到集合
- windowsCPE := &cpe.CPE{
- Part: *cpe.PartOperationSystem,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- }
- microsoftSet.Add(windowsCPE)
- ```
func (*CPESet) AdvancedFilter ¶
func (s *CPESet) AdvancedFilter(criteria *CPE, options *AdvancedMatchOptions) *CPESet
*
- AdvancedFilter 使用高级匹配选项过滤集合 *
- 高级过滤支持更复杂的匹配方式,如正则表达式、相似度匹配等。 *
- @param criteria *CPE 用作过滤条件的CPE对象
- @param options *AdvancedMatchOptions 高级匹配选项,如果为nil则使用默认选项
- @return *CPESet 包含所有匹配条件的CPE的新集合 *
- 示例:
- ```go
- // 创建高级过滤条件
- criteria := &cpe.CPE{
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- } *
- // 使用高级匹配选项
- options := cpe.NewAdvancedMatchOptions()
- options.MatchMode = "regex" // 使用正则表达式匹配 *
- // 过滤集合
- windows10Set := allProductsSet.AdvancedFilter(criteria, options)
- ```
func (*CPESet) Clear ¶
func (s *CPESet) Clear()
*
- Clear 清空集合中的所有CPE *
- 示例:
- ```go
- // 清空集合
- microsoftSet.Clear()
- fmt.Printf("集合大小: %d\n", microsoftSet.Size()) // 输出: 集合大小: 0
- ```
func (*CPESet) Contains ¶
*
- Contains 检查集合是否包含指定CPE *
- @param cpe *CPE 要检查的CPE对象
- @return bool 如果集合包含该CPE则返回true,否则返回false *
- 示例:
- ```go
- // 检查集合是否包含特定CPE
- if microsoftSet.Contains(windowsCPE) {
- fmt.Println("集合包含Windows CPE")
- }
- ```
func (*CPESet) Difference ¶
*
- Difference 计算两个集合的差集(在第一个集合中但不在第二个集合中的CPE) *
- @param other *CPESet 另一个CPE集合
- @return *CPESet 包含在s中但不在other中的CPE的新集合 *
- 示例:
- ```go
- // 计算两个集合的差集
- allWindowsSet := cpe.NewCPESet("All Windows", "All Windows versions")
- outdatedSet := cpe.NewCPESet("Outdated", "Outdated Windows versions") *
- // 添加CPE到各自集合... *
- // 计算差集,找出所有非过时的Windows版本
- supportedWindowsSet := allWindowsSet.Difference(outdatedSet)
- ```
func (*CPESet) Equals ¶
*
- Equals 检查两个集合是否完全相等 *
- 两个集合相等意味着它们包含完全相同的CPE集合。 *
- @param other *CPESet 要比较的另一个集合
- @return bool 如果两个集合包含相同的CPE则返回true,否则返回false *
- 示例:
- ```go
- // 检查两个集合是否相等
- if set1.Equals(set2) {
- fmt.Println("两个集合包含相同的CPE")
- }
- ```
func (*CPESet) Filter ¶
func (s *CPESet) Filter(criteria *CPE, options *MatchOptions) *CPESet
*
- Filter 根据条件过滤集合,使用基本匹配选项 *
- @param criteria *CPE 用作过滤条件的CPE对象
- @param options *MatchOptions 匹配选项,如果为nil则使用默认选项
- @return *CPESet 包含所有匹配条件的CPE的新集合 *
- 示例:
- ```go
- // 创建过滤条件
- criteria := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- } *
- // 使用自定义匹配选项过滤集合
- options := cpe.DefaultMatchOptions()
- options.IgnoreCase = true *
- // 过滤集合
- windowsSet := allProductsSet.Filter(criteria, options)
- ```
func (*CPESet) FindRelated ¶
func (s *CPESet) FindRelated(cpe *CPE, options *AdvancedMatchOptions) *CPESet
*
- FindRelated 查找与给定CPE相关的所有CPE *
- 此方法使用相似度匹配查找可能相关的CPE,适用于相似产品查找、漏洞关联分析等场景。 *
- @param cpe *CPE 用于查找相关CPE的参考CPE对象
- @param options *AdvancedMatchOptions 高级匹配选项,如果为nil则使用默认选项
- @return *CPESet 包含所有相关CPE的新集合 *
- 示例:
- ```go
- // 查找与Windows 10相关的所有CPE
- windows10CPE := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- } *
- // 找出所有相关CPE
- relatedCPEs := allProductsSet.FindRelated(windows10CPE, nil)
- fmt.Printf("找到%d个相关CPE\n", relatedCPEs.Size())
- ```
func (*CPESet) Intersection ¶
*
- Intersection 计算两个集合的交集(同时存在于两个集合中的CPE) *
- @param other *CPESet 另一个CPE集合
- @return *CPESet 仅包含同时存在于两个集合中的CPE的新集合 *
- 示例:
- ```go
- // 计算两个集合的交集
- windowsSet := cpe.NewCPESet("Windows", "Windows CPEs")
- vulnerableSet := cpe.NewCPESet("Vulnerable", "Vulnerable CPEs") *
- // 添加CPE到各自集合... *
- // 计算交集,找出有漏洞的Windows系统
- vulnerableWindowsSet := windowsSet.Intersection(vulnerableSet)
- ```
func (*CPESet) IsSubsetOf ¶
*
- IsSubsetOf 检查当前集合是否是另一个集合的子集 *
- 如果当前集合中的所有CPE都包含在other集合中,则当前集合是other的子集。 *
- @param other *CPESet 要检查的超集
- @return bool 如果当前集合是other的子集则返回true,否则返回false *
- 示例:
- ```go
- // 检查windows10Set是否是windowsSet的子集
- if windows10Set.IsSubsetOf(windowsSet) {
- fmt.Println("windows10Set是windowsSet的子集")
- }
- ```
func (*CPESet) IsSupersetOf ¶
*
- IsSupersetOf 检查当前集合是否是另一个集合的超集 *
- 如果other集合中的所有CPE都包含在当前集合中,则当前集合是other的超集。 *
- @param other *CPESet 要检查的子集
- @return bool 如果当前集合是other的超集则返回true,否则返回false *
- 示例:
- ```go
- // 检查windowsSet是否是windows10Set的超集
- if windowsSet.IsSupersetOf(windows10Set) {
- fmt.Println("windowsSet是windows10Set的超集")
- }
- ```
func (*CPESet) Remove ¶
*
- Remove 从集合中移除CPE *
- @param cpe *CPE 要移除的CPE对象
- @return bool 如果找到并移除了CPE则返回true,否则返回false *
- 示例:
- ```go
- // 移除指定的CPE
- removed := microsoftSet.Remove(windowsCPE)
- if removed {
- fmt.Println("CPE已从集合中移除")
- } else {
- fmt.Println("未在集合中找到该CPE")
- }
- ```
func (*CPESet) Sort ¶
*
- Sort 对集合中的CPE进行排序并返回排序后的切片 *
- 注意:此方法不改变集合本身,只返回排序后的CPE切片。 *
- @param sortBy string 排序字段,可以是"part"、"vendor"、"product"、"version"或其他属性
- @param ascending bool 是否按升序排序,false表示降序
- @return []*CPE 排序后的CPE切片 *
- 示例:
- ```go
- // 按产品名称升序排序
- sortedCPEs := microsoftSet.Sort("product", true) *
- // 按版本号降序排序(最新版本在前)
- sortedCPEs := microsoftSet.Sort("version", false)
- ```
func (*CPESet) ToSlice ¶
*
- ToSlice 将集合转换为CPE切片 *
- 此方法用于获取集合中所有CPE的切片形式,便于遍历和排序。 *
- @return []*CPE 包含集合中所有CPE的切片
func (*CPESet) ToString ¶
*
- ToString 返回集合的字符串表示 *
- 返回的字符串包含集合的名称、描述、大小以及所有CPE的列表。 *
- @return string 集合的字符串表示 *
- 示例:
- ```go
- // 获取并打印集合的字符串表示
- fmt.Println(microsoftSet.ToString())
- ```
func (*CPESet) Union ¶
*
- Union 计算两个集合的并集(包含在任一集合中的所有CPE) *
- @param other *CPESet 另一个CPE集合
- @return *CPESet 包含两个集合所有唯一CPE的新集合 *
- 示例:
- ```go
- // 计算两个集合的并集
- microsoftSet := cpe.NewCPESet("Microsoft", "Microsoft CPEs")
- appleSet := cpe.NewCPESet("Apple", "Apple CPEs") *
- // 添加CPE到各自集合... *
- // 计算并集
- allVendorsSet := microsoftSet.Union(appleSet)
- fmt.Printf("并集大小: %d\n", allVendorsSet.Size())
- ```
type CVEReference ¶
type CVEReference struct {
// CVEID 是CVE的唯一标识符,例如 CVE-2021-44228
CVEID string
// Description 是CVE的描述
Description string
// PublishedDate 是CVE发布日期
PublishedDate time.Time
// LastModifiedDate 是CVE最后修改日期
LastModifiedDate time.Time
// CVSSScore 是CVE的CVSS评分 (0.0-10.0)
CVSSScore float64
// Severity 是CVE的严重性级别 (Low, Medium, High, Critical)
Severity string
// References 是CVE的参考链接
References []string
// AffectedCPEs 是受影响的CPE URI列表
AffectedCPEs []string
// Metadata 是CVE的额外元数据
Metadata map[string]interface{}
}
CVEReference 表示一个CVE安全漏洞
func GetCVEInfo ¶
func GetCVEInfo(cves []*CVEReference, cveID string) *CVEReference
GetCVEInfo 获取CVE详细信息 输入:
- cves: []*CVEReference 类型,CVE引用对象的切片
- cveID: string 类型,待查询的CVE ID,不区分大小写,格式会被标准化
输出:
- *CVEReference: 返回匹配的CVE引用对象,如果未找到则返回nil
行为:
- 会使用github.com/scagogogo/cve库标准化CVE ID的格式
- 从CVE列表中查找完全匹配的CVE ID
示例:
cves := []*CVEReference{...} // 从数据源加载的CVE列表
cve := GetCVEInfo(cves, "CVE-2021-44228")
if cve != nil {
fmt.Printf("CVE描述: %s\n", cve.Description)
fmt.Printf("严重级别: %s (CVSS: %.1f)\n", cve.Severity, cve.CVSSScore)
} else {
fmt.Println("未找到指定的CVE")
}
func GetCVEInfoImpl ¶
func GetCVEInfoImpl(cveID string) (*CVEReference, error)
*
- GetCVEInfoImpl 获取CVE漏洞详细信息 *
- 此函数根据CVE ID查询漏洞的详细信息,包括描述、严重性、发布日期等。
- 用于深入了解特定漏洞的技术细节和影响范围,为安全评估和修复决策提供依据。 *
- 参数:
- - cveID: 标准格式的CVE标识符,如"CVE-2021-44228" *
- 返回:
- - *CVEReference: 包含漏洞详细信息的结构体指针,若未找到则为nil
- - error: 查询过程中遇到的错误,成功时为nil *
- 使用示例:
- ```go
- // 获取著名的Log4Shell漏洞信息
- cveInfo, err := cpe.GetCVEInfoImpl("CVE-2021-44228")
- if err != nil {
- log.Fatalf("获取CVE信息失败: %v", err)
- } *
- if cveInfo != nil {
- fmt.Printf("CVE-2021-44228 详情:\n")
- fmt.Printf("漏洞名称: %s\n", cveInfo.CVEID)
- fmt.Printf("公开日期: %s\n", cveInfo.PublishedDate)
- fmt.Printf("最后修改: %s\n", cveInfo.LastModifiedDate)
- fmt.Printf("严重性: %s (基础评分: %.1f)\n", cveInfo.Severity, cveInfo.CVSSScore)
- fmt.Printf("描述: %s\n", cveInfo.Description) *
- fmt.Printf("影响的产品数量: %d\n", len(cveInfo.AffectedCPEs))
- for i, product := range cveInfo.AffectedCPEs[:3] { // 只显示前3个
- fmt.Printf(" %d. %s\n", i+1, product)
- }
- } else {
- fmt.Println("未找到此CVE的信息")
- }
- ``` *
- 注意事项:
- - 需要预先初始化数据源,通常是通过DownloadAllNVDData完成
- - CVE ID的格式应符合标准(CVE-YYYY-NNNNN),将自动进行格式标准化
- - 返回的信息完整度取决于数据源中可用的数据
- - 某些较新或较罕见的CVE可能缺乏完整信息
func NewCVEReference ¶
func NewCVEReference(cveID string) *CVEReference
NewCVEReference 创建一个新的CVE引用 输入:
- cveID: string 类型,CVE的唯一标识符,例如 "CVE-2021-44228"
输出:
- *CVEReference: 返回初始化的CVE引用对象,包含空的References和AffectedCPEs切片, 以及初始化的Metadata映射,PublishedDate和LastModifiedDate设置为当前时间
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.Description = "Log4j远程代码执行漏洞"
cve.SetSeverity(10.0) // 设置为Critical级别
func QueryByProduct ¶
func QueryByProduct(cves []*CVEReference, vendor, product string, version string) []*CVEReference
QueryByProduct 根据产品信息查询相关CVE 输入:
- cves: []*CVEReference 类型,CVE引用对象的切片
- vendor: string 类型,供应商名称,不区分大小写,空字符串表示匹配任何供应商
- product: string 类型,产品名称,不区分大小写,空字符串表示匹配任何产品
- version: string 类型,产品版本,区分大小写,空字符串表示匹配任何版本,"*"也表示任何版本
输出:
- []*CVEReference: 返回匹配的CVE引用对象的切片
行为:
- 解析每个CVE的受影响CPE列表
- 支持解析CPE 2.2和CPE 2.3格式
- 根据供应商、产品名和版本进行匹配过滤
- 对于每个CVE,一旦发现一个匹配的CPE,便立即添加到结果中并跳过该CVE的其余CPE,避免重复
- 匹配时vendor和product不区分大小写,但version区分大小写
- 使用scagogogo/cve库对CVE ID进行标准化和验证
示例:
cves := []*CVEReference{...} // 从数据源加载的CVE列表
// 查找影响Apache Log4j的所有CVE
apacheLog4jCVEs := QueryByProduct(cves, "apache", "log4j", "")
// 查找影响特定版本的CVE
versionCVEs := QueryByProduct(cves, "apache", "log4j", "2.0")
// 查找特定供应商的所有产品漏洞
vendorCVEs := QueryByProduct(cves, "apache", "", "")
func (*CVEReference) AddAffectedCPE ¶
func (cve *CVEReference) AddAffectedCPE(cpeURI string)
AddAffectedCPE 添加一个受影响的CPE 输入:
- cpeURI: string 类型,要添加的CPE URI,支持CPE 2.2格式(cpe:/)或CPE 2.3格式(cpe:2.3:) 例如:"cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*" 或 "cpe:/a:apache:log4j:2.0"
输出:
- 无返回值,直接修改CVEReference对象
行为:
- 如果CPE已存在于AffectedCPEs列表中,则不会重复添加
- 添加CPE后,会自动更新LastModifiedDate为当前时间
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.AddAffectedCPE("cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*")
func (*CVEReference) AddReference ¶
func (cve *CVEReference) AddReference(reference string)
AddReference 添加一个参考链接 输入:
- reference: string 类型,要添加的参考链接URL或其他引用 例如:"https://nvd.nist.gov/vuln/detail/CVE-2021-44228"
输出:
- 无返回值,直接修改CVEReference对象
行为:
- 如果参考链接已存在于References列表中,则不会重复添加
- 添加链接后,会自动更新LastModifiedDate为当前时间
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.AddReference("https://nvd.nist.gov/vuln/detail/CVE-2021-44228")
cve.AddReference("https://www.cve.org/CVERecord?id=CVE-2021-44228")
func (*CVEReference) GetMetadata ¶
func (cve *CVEReference) GetMetadata(key string) (interface{}, bool)
GetMetadata 获取元数据 输入:
- key: string 类型,要获取的元数据键名
输出:
- interface{}: 返回与键关联的值,如果键不存在则为nil
- bool: 指示键是否存在 true - 键存在 false - 键不存在
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.SetMetadata("exploitAvailable", true)
value, exists := cve.GetMetadata("exploitAvailable")
if exists {
isExploitable := value.(bool) // 将返回true
}
_, notExists := cve.GetMetadata("nonExistentKey")
// notExists将为false
func (*CVEReference) RemoveAffectedCPE ¶
func (cve *CVEReference) RemoveAffectedCPE(cpeURI string) bool
RemoveAffectedCPE 移除一个受影响的CPE 输入:
- cpeURI: string 类型,要移除的CPE URI
输出:
- bool: 移除操作是否成功 true - 找到并移除了指定的CPE false - 未找到指定的CPE,无需移除
行为:
- 成功移除CPE后,会自动更新LastModifiedDate为当前时间
- 如果移除成功,受影响的CPE列表长度将减少1
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.AddAffectedCPE("cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*")
removed := cve.RemoveAffectedCPE("cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*") // 返回 true
notRemoved := cve.RemoveAffectedCPE("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*") // 返回 false
func (*CVEReference) RemoveMetadata ¶
func (cve *CVEReference) RemoveMetadata(key string) bool
RemoveMetadata 移除元数据 输入:
- key: string 类型,要移除的元数据键名
输出:
- bool: 移除操作是否成功 true - 键存在并被成功移除 false - 键不存在,无需移除
行为:
- 成功移除元数据后,会自动更新LastModifiedDate为当前时间
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.SetMetadata("exploitAvailable", true)
removed := cve.RemoveMetadata("exploitAvailable") // 返回true
notRemoved := cve.RemoveMetadata("nonExistentKey") // 返回false
func (*CVEReference) SetMetadata ¶
func (cve *CVEReference) SetMetadata(key string, value interface{})
SetMetadata 设置元数据 输入:
- key: string 类型,元数据的键名
- value: interface{} 类型,元数据的值,可以是任意类型
输出:
- 无返回值,直接修改CVEReference对象的Metadata映射
行为:
- 如果键已存在,将覆盖原有值
- 设置后,会自动更新LastModifiedDate为当前时间
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.SetMetadata("exploitAvailable", true)
cve.SetMetadata("patchDate", "2021-12-10")
cve.SetMetadata("affectedVersions", []string{"2.0", "2.1", "2.2"})
func (*CVEReference) SetSeverity ¶
func (cve *CVEReference) SetSeverity(cvssScore float64)
SetSeverity 设置CVE的严重性级别 输入:
- cvssScore: float64 类型,CVE的CVSS评分,取值范围为0.0-10.0
输出:
- 无返回值,直接修改CVEReference对象的CVSSScore和Severity字段
行为:
- 根据CVSS评分自动设置对应的严重性级别:
- 9.0-10.0: "Critical" (危急)
- 7.0-8.9: "High" (高危)
- 4.0-6.9: "Medium" (中危)
- 0.0-3.9: "Low" (低危)
- 设置后,会自动更新LastModifiedDate为当前时间
示例:
cve := NewCVEReference("CVE-2021-44228")
cve.SetSeverity(10.0) // 设置为Critical级别
cve.SetSeverity(5.5) // 设置为Medium级别
cve.SetSeverity(2.0) // 设置为Low级别
type CacheSettings ¶
type CacheSettings struct {
// 是否启用缓存
Enabled bool
// 缓存目录
Directory string
// 缓存过期时间(小时)
ExpiryHours int
// 缓存文件名模板
FileNameTemplate string
}
CacheSettings 缓存设置
type Component ¶
type Component interface {
// String 返回组件的字符串表示
String() string
// IsANY 判断组件是否为ANY值
IsANY() bool
// IsNA 判断组件是否为NA值
IsNA() bool
// IsSet 判断组件是否设置了有效值(非ANY/NA/空)
IsSet() bool
// Normalize 标准化组件值
Normalize() string
}
Component 接口定义CPE组件类型的通用行为
type DataSourceAuth ¶
type DataSourceAuth struct {
// API密钥
APIKey string
// 用户名
Username string
// 密码
Password string
// 认证令牌
Token string
// 自定义头信息
Headers map[string]string
}
DataSourceAuth 数据源认证信息
type DataSourceType ¶
type DataSourceType string
DataSourceType 表示数据源类型
const ( // DataSourceNVD NVD数据源 DataSourceNVD DataSourceType = "NVD" // DataSourceMITRE MITRE数据源 DataSourceMITRE DataSourceType = "MITRE" // DataSourceGitHub GitHub安全公告 DataSourceGitHub DataSourceType = "GitHub" // DataSourceRedHatCVE RedHat CVE数据库 DataSourceRedHatCVE DataSourceType = "RedHat" // DataSourceOWASP OWASP数据源 DataSourceOWASP DataSourceType = "OWASP" // DataSourceCustom 自定义数据源 DataSourceCustom DataSourceType = "Custom" )
type Edition ¶
type Edition string
*
- Edition 表示CPE中的版本类型组件 *
- 在CPE规范中,Edition表示产品的版本类型或发行类型,如"SP1"(Service Pack 1)、
- "企业版"、"专业版"等。Edition也可以使用特殊值"*"(任意版本类型)或"-"(不适用)。 *
- 版本类型与具体版本号(Version)不同,它描述的是产品的发行类型而非版本号。
- 在CPE 2.3规范中,Edition字段部分功能已被更精细的SoftwareEdition字段取代,
- 但为了向后兼容仍然保留。 *
- 示例:
- ```go
- // 创建一个表示Windows 10专业版的CPE
- win10ProCPE := &cpe.CPE{
- Part: *cpe.PartOperationSystem,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- Edition: cpe.Edition("pro"),
- } *
- // 使用通配符匹配任意版本类型
- windowsAnyCPE := &cpe.CPE{
- Part: *cpe.PartOperationSystem,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Edition: cpe.Edition("*"), // 匹配任意版本类型
- } *
- // 创建搜索条件,查找特定版本类型的产品
- searchCriteria := &cpe.CPE{
- Edition: cpe.Edition("enterprise"),
- }
- options := cpe.DefaultMatchOptions()
- results := cpe.Search(cpeList, searchCriteria, options)
- ```
type ErrorType ¶
type ErrorType int
*
- ErrorType 表示CPE操作过程中可能出现的错误类型枚举 *
- 这个枚举用于区分不同种类的CPE错误,便于错误处理和日志记录。
- 每种错误类型对应特定的错误情况,使用常量定义便于代码维护。
const ( // ErrorTypeParsingFailed 表示CPE字符串解析失败的错误类型 ErrorTypeParsingFailed ErrorType = iota // ErrorTypeInvalidFormat 表示CPE格式无效的错误类型 ErrorTypeInvalidFormat // ErrorTypeInvalidPart 表示CPE部件值无效的错误类型 ErrorTypeInvalidPart // ErrorTypeInvalidAttribute 表示CPE属性值无效的错误类型 ErrorTypeInvalidAttribute // ErrorTypeNotFound 表示未找到请求的资源或对象的错误类型 ErrorTypeNotFound // ErrorTypeOperationFailed 表示CPE相关操作执行失败的错误类型 ErrorTypeOperationFailed )
type Expression ¶
type Expression interface {
/**
* Type 返回表达式的类型
*
* @return ExpressionType 表达式类型,可以是CPE、AND、OR或NOT
*/
Type() ExpressionType
/**
* Evaluate 评估表达式是否匹配目标CPE
*
* @param target *CPE 要匹配的目标CPE
* @return bool 如果表达式匹配目标CPE返回true,否则返回false
*/
Evaluate(target *CPE) bool
/**
* String 返回表达式的字符串表示
*
* @return string 表达式的字符串形式,可用于日志记录或调试
*/
String() string
}
*
- Expression CPE适用性语言表达式接口 *
- 这个接口定义了CPE适用性语言中表达式的共同行为。
- 所有类型的表达式(单个CPE、AND、OR、NOT)都实现了这个接口,
- 提供了获取表达式类型、评估表达式和字符串表示的方法。
func ParseExpression ¶
func ParseExpression(expr string) (Expression, error)
*
- ParseExpression 解析CPE适用性语言表达式 *
- CPE适用性语言允许通过逻辑表达式组合多个CPE,表达复杂的匹配条件。
- 支持的表达式类型包括:
- - 单个CPE表达式: "cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*"
- - AND逻辑组合: "AND(expr1, expr2, ...)"
- - OR逻辑组合: "OR(expr1, expr2, ...)"
- - NOT逻辑求反: "NOT(expr)" *
- @param expr 要解析的表达式字符串
- @return (Expression, error) 成功时返回解析后的表达式对象,失败时返回nil和错误 *
- @error 当表达式格式无效时返回错误
- @error 当子表达式解析失败时返回错误 *
- 示例:
- ```go
- // 解析单个CPE表达式
- expr1, err := cpe.ParseExpression("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
- if err != nil {
- log.Fatalf("解析表达式失败: %v", err)
- } *
- // 解析OR表达式
- orExpr, err := cpe.ParseExpression("OR(cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*, cpe:2.3:a:microsoft:windows:11:*:*:*:*:*:*:*)")
- if err != nil {
- log.Fatalf("解析OR表达式失败: %v", err)
- } *
- // 解析AND表达式
- andExpr, err := cpe.ParseExpression("AND(cpe:2.3:a:microsoft:*:*:*:*:*:*:*:*:*, cpe:2.3:a:*:windows:*:*:*:*:*:*:*:*)")
- if err != nil {
- log.Fatalf("解析AND表达式失败: %v", err)
- } *
- // 解析NOT表达式
- notExpr, err := cpe.ParseExpression("NOT(cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*)")
- if err != nil {
- log.Fatalf("解析NOT表达式失败: %v", err)
- } *
- // 评估表达式
- targetCPE, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:11:*:*:*:*:*:*:*")
- fmt.Println("Windows 11匹配OR表达式:", orExpr.Evaluate(targetCPE))
- // 输出: Windows 11匹配OR表达式: true
- ```
type ExpressionType ¶
type ExpressionType int
ExpressionType 表达式类型
const ( // ExpressionTypeCPE 单个CPE匹配表达式 ExpressionTypeCPE ExpressionType = iota // ExpressionTypeAND 逻辑AND表达式 ExpressionTypeAND // ExpressionTypeOR 逻辑OR表达式 ExpressionTypeOR // ExpressionTypeNOT 逻辑NOT表达式 ExpressionTypeNOT )
type FieldMatchOption ¶
type FieldMatchOption struct {
// 匹配权重 (0.0-1.0)
Weight float64
// 是否必须匹配此字段
Required bool
// 匹配方法
MatchMethod string
}
FieldMatchOption 定义字段特定的匹配选项
type FileStorage ¶
type FileStorage struct {
// contains filtered or unexported fields
}
FileStorage 是一个基于文件系统的存储实现
func NewFileStorage ¶
func NewFileStorage(baseDir string, useCache bool) (*FileStorage, error)
*
- NewFileStorage 创建基于文件系统的CPE数据存储实例 *
- 此函数会在指定的基础目录下创建必要的子目录结构,包括cpes、cves、dictionary和metadata文件夹,
- 用于存储不同类型的数据。还可以选择是否启用内存缓存以提高性能。 *
- @param baseDir 存储数据的基础目录路径,如果不存在会自动创建
- @param useCache 是否使用内存缓存来提高读取性能
- @return (*FileStorage, error) 成功时返回FileStorage实例指针,失败时返回nil和错误 *
- @error 当无法创建基础目录或子目录时,返回错误
- @error 当启用缓存但无法初始化缓存时,返回错误 *
- 示例:
- ```go
- // 创建临时目录用于存储CPE数据
- tempDir, err := os.MkdirTemp("", "cpe-storage-*")
- if err != nil {
- log.Fatalf("创建临时目录失败: %v", err)
- }
- defer os.RemoveAll(tempDir) // 在程序结束时清理 *
- // 创建带缓存的文件存储
- storage, err := cpe.NewFileStorage(tempDir, true)
- if err != nil {
- log.Fatalf("创建存储失败: %v", err)
- }
- defer storage.Close() // 确保资源正确释放 *
- // 现在可以使用storage进行CPE的存储和检索操作
- ```
func (*FileStorage) AdvancedSearchCPE ¶
func (f *FileStorage) AdvancedSearchCPE(criteria *CPE, options *AdvancedMatchOptions) ([]*CPE, error)
AdvancedSearchCPE 高级搜索CPE
func (*FileStorage) CPEFilePath ¶
func (fs *FileStorage) CPEFilePath(id string) string
CPEFilePath 根据CPE ID获取CPE文件路径
func (*FileStorage) CVEFilePath ¶
func (fs *FileStorage) CVEFilePath(id string) string
CVEFilePath 根据CVE ID获取CVE文件路径
func (*FileStorage) DeleteCPE ¶
func (f *FileStorage) DeleteCPE(uri string) error
DeleteCPE 删除一个CPE记录
func (*FileStorage) DeleteCVE ¶
func (fs *FileStorage) DeleteCVE(cveID string) error
DeleteCVE 删除CVE信息
func (*FileStorage) DictionaryFilePath ¶
func (fs *FileStorage) DictionaryFilePath() string
DictionaryFilePath 获取字典文件路径
func (*FileStorage) FindCPEsByCVE ¶
func (fs *FileStorage) FindCPEsByCVE(cveID string) ([]*CPE, error)
FindCPEsByCVE 查找与CVE关联的CPE
func (*FileStorage) FindCVEsByCPE ¶
func (fs *FileStorage) FindCVEsByCPE(cpe *CPE) ([]*CVEReference, error)
FindCVEsByCPE 查找与CPE关联的CVE
func (*FileStorage) MetadataFilePath ¶
func (fs *FileStorage) MetadataFilePath(key string) string
MetadataFilePath 根据键获取元数据文件路径
func (*FileStorage) RetrieveCPE ¶
func (fs *FileStorage) RetrieveCPE(id string) (*CPE, error)
*
- RetrieveCPE 根据CPE URI检索CPE对象 *
- 此方法首先尝试从内存缓存(如果启用)中获取CPE,缓存未命中时则从文件系统读取CPE数据。
- 检索到的CPE会被添加到缓存中(如果启用缓存)以加速后续访问。 *
- @param id CPE URI,作为检索CPE的唯一标识符,如"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*"
- @return (*CPE, error) 成功时返回检索到的CPE结构体指针,失败时返回nil和错误 *
- @error 当CPE不存在时,返回ErrNotFound
- @error 当无法读取文件或解析JSON数据时,返回相应错误 *
- 示例:
- ```go
- // 以Windows 10的CPE URI为例
- cpeURI := "cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*" *
- // 从存储中检索CPE
- winCPE, err := storage.RetrieveCPE(cpeURI)
- if err != nil {
- if err == cpe.ErrNotFound {
- log.Printf("CPE不存在: %s", cpeURI)
- } else {
- log.Fatalf("检索CPE失败: %v", err)
- }
- } else {
- fmt.Printf("成功检索到CPE: %s (厂商: %s, 产品: %s)\n",
- cpeURI, winCPE.Vendor, winCPE.ProductName)
- }
- ```
func (*FileStorage) RetrieveCVE ¶
func (fs *FileStorage) RetrieveCVE(cveID string) (*CVEReference, error)
RetrieveCVE 查询CVE
func (*FileStorage) RetrieveDictionary ¶
func (fs *FileStorage) RetrieveDictionary() (*CPEDictionary, error)
RetrieveDictionary 检索CPE字典
func (*FileStorage) RetrieveModificationTimestamp ¶
func (fs *FileStorage) RetrieveModificationTimestamp(key string) (time.Time, error)
RetrieveModificationTimestamp 检索最后修改时间
func (*FileStorage) SearchCPE ¶
func (f *FileStorage) SearchCPE(criteria *CPE, options *MatchOptions) ([]*CPE, error)
*
- SearchCPE 根据条件搜索CPE记录 *
- 此方法允许根据指定的查询条件和选项搜索CPE数据库。
- 可以搜索CPE的各种属性,如供应商名称、产品名称或版本号。 *
- @param criteria *CPE 搜索条件,包含要匹配的CPE字段,如果为nil则返回所有CPE
- @param options *MatchOptions 匹配选项,控制匹配行为,如忽略版本或使用正则表达式
- @return ([]*CPE, error) 成功时返回匹配的CPE列表,失败时返回nil和错误 *
- @error 当读取目录或文件失败时,返回相应错误
- @error 当解析CPE数据失败时,返回相应错误 *
- 示例:
- ```go
- // 搜索所有Microsoft的产品
- criteria := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- } *
- // 设置匹配选项,忽略版本匹配
- options := &cpe.MatchOptions{
- IgnoreVersion: true,
- } *
- // 执行搜索
- results, err := storage.SearchCPE(criteria, options)
- if err != nil {
- log.Fatalf("搜索CPE失败: %v", err)
- } *
- // 显示搜索结果
- fmt.Printf("找到 %d 个匹配的CPE:\n", len(results))
- for i, cpeItem := range results {
- fmt.Printf("%d. %s (产品: %s, 版本: %s)\n",
- i+1, cpeItem.GetURI(), cpeItem.ProductName, cpeItem.Version)
- } *
- // 搜索所有CPE
- allCPEs, err := storage.SearchCPE(nil, nil)
- if err != nil {
- log.Fatalf("获取所有CPE失败: %v", err)
- }
- fmt.Printf("总共有 %d 个CPE记录\n", len(allCPEs))
- ```
func (*FileStorage) SearchCVE ¶
func (fs *FileStorage) SearchCVE(query string, options *SearchOptions) ([]*CVEReference, error)
SearchCVE 搜索CVE
func (*FileStorage) StoreCVE ¶
func (fs *FileStorage) StoreCVE(cve *CVEReference) error
StoreCVE 存储CVE
func (*FileStorage) StoreDictionary ¶
func (fs *FileStorage) StoreDictionary(dict *CPEDictionary) error
*
- StoreDictionary 存储CPE字典 *
- 此方法将整个CPE字典序列化为JSON并存储到文件系统中。如果启用了缓存,
- 也会同时更新内存缓存。还会更新字典的最后修改时间戳。 *
- @param dict 要存储的CPE字典,包含一组CPE项和元数据
- @return error 成功时返回nil,失败时返回错误 *
- @error 当参数为nil时,返回ErrInvalidData
- @error 当序列化字典失败时,返回错误
- @error 当写入文件失败时,返回错误
- @error 当更新缓存失败时,返回错误 *
- 示例:
- ```go
- // 创建一个新的CPE字典
- dictionary := &cpe.CPEDictionary{
- GeneratedAt: time.Now(),
- SchemaVersion: "2.3",
- Items: make([]*cpe.CPEItem, 0),
- } *
- // 添加CPE项到字典
- windowsCPE, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*") *
- // 创建Windows 10的字典项
- windowsItem := &cpe.CPEItem{
- Name: windowsCPE.Cpe23,
- Title: "Microsoft Windows 10",
- CPE: windowsCPE,
- References: []cpe.Reference{
- {
- URL: "https://www.microsoft.com/windows",
- Type: "vendor",
- },
- },
- } *
- // 添加到字典
- dictionary.Items = append(dictionary.Items, windowsItem) *
- // 存储字典
- err := storage.StoreDictionary(dictionary)
- if err != nil {
- log.Fatalf("存储CPE字典失败: %v", err)
- } *
- fmt.Printf("成功存储包含 %d 条CPE记录的字典\n", len(dictionary.Items))
- ```
func (*FileStorage) StoreModificationTimestamp ¶
func (fs *FileStorage) StoreModificationTimestamp(key string, timestamp time.Time) error
StoreModificationTimestamp 存储最后修改时间
func (*FileStorage) UpdateCVE ¶
func (fs *FileStorage) UpdateCVE(cve *CVEReference) error
UpdateCVE 更新CVE信息
type Language ¶
type Language string
*
- Language 表示CPE中的语言组件 *
- 在CPE规范中,Language用于标识软件的语言版本。通常使用ISO 639-2标准的语言代码:
- 例如"zh"(中文)、"en"(英文)、"fr"(法语)等。Language也可以使用特殊值"*"(任意语言)
- 或"-"(不适用)。 *
- Language字段对于区分同一软件的不同语言版本非常重要,因为不同语言版本可能具有
- 不同的安全漏洞或兼容性问题。 *
- 示例:
- ```go
- // 创建一个表示中文版Microsoft Office的CPE
- officeZhCPE := &cpe.CPE{
- Part: *cpe.PartApplication,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("office"),
- Version: cpe.Version("2019"),
- Language: cpe.Language("zh"),
- } *
- // 使用特殊值匹配任意语言版本
- officeAnyCPE := &cpe.CPE{
- Part: *cpe.PartApplication,
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("office"),
- Language: cpe.Language("*"), // 匹配任意语言
- } *
- // 创建搜索条件,查找特定语言的产品
- searchCriteria := &cpe.CPE{
- Language: cpe.Language("ja"), // 查找日语版本
- }
- options := cpe.DefaultMatchOptions()
- results := cpe.Search(cpeList, searchCriteria, options)
- ```
type MatchOptions ¶
type MatchOptions struct {
// 是否忽略版本匹配
// 设为true时版本号不参与匹配判断,适用于只需比较产品名称或供应商的场景
IgnoreVersion bool
// 是否允许子版本匹配
// 设为true时,查询版本"1.0"可匹配"1.0"、"1.0.1"、"1.0.2"等所有子版本
// 仅当IgnoreVersion为false且VersionRange为false时有效
AllowSubVersions bool
// 使用正则表达式匹配
// 设为true时,Vendor、ProductName等字符串字段将使用正则表达式进行匹配
// 注意:正则表达式匹配会降低性能,大规模匹配时慎用
UseRegex bool
// 比较版本范围而不是精确匹配
// 设为true时,将使用MinVersion和MaxVersion定义的版本范围进行匹配
// 此选项优先于AllowSubVersions
VersionRange bool
// 最小版本(含)
// 指定版本范围的下限,当VersionRange为true时生效
// 匹配时CPE版本必须大于或等于此版本
MinVersion string
// 最大版本(含)
// 指定版本范围的上限,当VersionRange为true时生效
// 匹配时CPE版本必须小于或等于此版本
MaxVersion string
}
*
- MatchOptions 匹配选项结构体 *
- 用于配置CPE匹配过程中的各种行为选项,包括版本匹配逻辑、正则表达式支持等。
- 此结构体可用于精细控制Search和matchCPE函数的匹配行为。 *
- 注意事项:
- - 启用正则表达式会对性能有一定影响,大规模CPE集合时要谨慎使用
- - 版本范围和子版本匹配不能同时生效,启用VersionRange会优先于AllowSubVersions *
- 示例:
- ```go
- // 创建匹配选项,忽略版本匹配
- options := &cpe.MatchOptions{
- IgnoreVersion: true,
- } *
- // 创建匹配选项,使用版本范围匹配
- options := &cpe.MatchOptions{
- VersionRange: true,
- MinVersion: "2.0",
- MaxVersion: "3.5",
- }
- ```
func DefaultMatchOptions ¶
func DefaultMatchOptions() *MatchOptions
*
- DefaultMatchOptions 返回默认匹配选项 *
- 创建并返回一个预设默认值的MatchOptions实例,用于简化匹配选项的创建过程。
- 默认配置下:
- - 会考虑版本匹配(IgnoreVersion = false)
- - 允许子版本匹配(AllowSubVersions = true)
- - 不使用正则表达式匹配(UseRegex = false)
- - 不使用版本范围匹配(VersionRange = false) *
- @return *MatchOptions 预设了默认值的匹配选项对象 *
- 示例:
- ```go
- // 使用默认匹配选项
- options := cpe.DefaultMatchOptions() *
- // 在默认选项基础上修改
- options := cpe.DefaultMatchOptions()
- options.UseRegex = true
- ``` *
- 注意事项:
- - 返回的是指针类型,可以直接修改其属性
- - 在大多数简单匹配场景下,默认选项已经能满足需求
type MemoryStorage ¶
type MemoryStorage struct {
// contains filtered or unexported fields
}
MemoryStorage 是一个基于内存的存储实现
func (*MemoryStorage) AdvancedSearchCPE ¶
func (ms *MemoryStorage) AdvancedSearchCPE(criteria *CPE, options *AdvancedMatchOptions) ([]*CPE, error)
AdvancedSearchCPE 高级搜索CPE
func (*MemoryStorage) DeleteCPE ¶
func (ms *MemoryStorage) DeleteCPE(id string) error
DeleteCPE 删除CPE
func (*MemoryStorage) DeleteCVE ¶
func (ms *MemoryStorage) DeleteCVE(cveID string) error
DeleteCVE 删除CVE信息
func (*MemoryStorage) FindCPEsByCVE ¶
func (ms *MemoryStorage) FindCPEsByCVE(cveID string) ([]*CPE, error)
FindCPEsByCVE 查找与CVE关联的CPE
func (*MemoryStorage) FindCVEsByCPE ¶
func (ms *MemoryStorage) FindCVEsByCPE(cpe *CPE) ([]*CVEReference, error)
FindCVEsByCPE 查找与CPE关联的CVE
func (*MemoryStorage) RetrieveCPE ¶
func (ms *MemoryStorage) RetrieveCPE(id string) (*CPE, error)
RetrieveCPE 根据ID检索CPE
func (*MemoryStorage) RetrieveCVE ¶
func (ms *MemoryStorage) RetrieveCVE(cveID string) (*CVEReference, error)
RetrieveCVE 根据CVE ID检索CVE信息
func (*MemoryStorage) RetrieveDictionary ¶
func (ms *MemoryStorage) RetrieveDictionary() (*CPEDictionary, error)
RetrieveDictionary 检索CPE字典
func (*MemoryStorage) RetrieveModificationTimestamp ¶
func (ms *MemoryStorage) RetrieveModificationTimestamp(key string) (time.Time, error)
RetrieveModificationTimestamp 检索最后修改时间
func (*MemoryStorage) SearchCPE ¶
func (ms *MemoryStorage) SearchCPE(criteria *CPE, options *MatchOptions) ([]*CPE, error)
SearchCPE 搜索CPE
func (*MemoryStorage) SearchCVE ¶
func (ms *MemoryStorage) SearchCVE(query string, options *SearchOptions) ([]*CVEReference, error)
SearchCVE 搜索CVE
func (*MemoryStorage) StoreCVE ¶
func (ms *MemoryStorage) StoreCVE(cve *CVEReference) error
StoreCVE 存储CVE信息
func (*MemoryStorage) StoreDictionary ¶
func (ms *MemoryStorage) StoreDictionary(dict *CPEDictionary) error
StoreDictionary 存储CPE字典
func (*MemoryStorage) StoreModificationTimestamp ¶
func (ms *MemoryStorage) StoreModificationTimestamp(key string, timestamp time.Time) error
StoreModificationTimestamp 存储最后修改时间
func (*MemoryStorage) UpdateCPE ¶
func (ms *MemoryStorage) UpdateCPE(cpe *CPE) error
UpdateCPE 更新CPE
func (*MemoryStorage) UpdateCVE ¶
func (ms *MemoryStorage) UpdateCVE(cve *CVEReference) error
UpdateCVE 更新CVE信息
type MultiSourceVulnerabilitySearch ¶
type MultiSourceVulnerabilitySearch struct {
// 数据源列表
Sources []*VulnDataSource
// 并发级别
ConcurrencyLevel int
// 超时时间(秒)
TimeoutSeconds int
// 是否合并结果
MergeResults bool
}
MultiSourceVulnerabilitySearch 多数据源漏洞搜索
func CreateDefaultMultiSourceSearch ¶
func CreateDefaultMultiSourceSearch() *MultiSourceVulnerabilitySearch
CreateDefaultMultiSourceSearch 创建默认的多源搜索
func NewMultiSourceSearch ¶
func NewMultiSourceSearch(sources []*VulnDataSource) *MultiSourceVulnerabilitySearch
NewMultiSourceSearch 创建新的多数据源搜索
func (*MultiSourceVulnerabilitySearch) SearchByCPE ¶
func (ms *MultiSourceVulnerabilitySearch) SearchByCPE(cpe *CPE) ([]*CVEReference, error)
SearchByCPE 根据CPE在多个数据源中搜索
func (*MultiSourceVulnerabilitySearch) SearchByCVE ¶
func (ms *MultiSourceVulnerabilitySearch) SearchByCVE(cveID string) ([]*CVEReference, error)
SearchByCVE 根据CVE ID在多个数据源中搜索
type NOTExpression ¶
type NOTExpression struct {
Expression Expression
}
NOTExpression 表示逻辑NOT表达式
func (*NOTExpression) Evaluate ¶
func (e *NOTExpression) Evaluate(target *CPE) bool
Evaluate 评估表达式是否匹配目标CPE
type NVDCPEData ¶
type NVDCPEData struct {
// CPEDictionary 包含所有官方注册的CPE条目及其详细信息
// 通过此字段可以获取特定CPE的标准化表示和元数据
CPEDictionary *CPEDictionary
// CPEMatchData 包含CPE与CVE之间的双向映射关系
// 用于快速查找特定CPE关联的漏洞,或特定漏洞影响的产品
CPEMatchData *CPEMatchData
// DownloadTime 记录数据下载的时间戳
// 可用于判断数据的新鲜度,决定是否需要更新
DownloadTime time.Time
}
*
- NVDCPEData 集成了从NVD获取的CPE和CVE关联数据 *
- 此结构体封装了从美国国家漏洞数据库(NVD)获取的多种数据,包括CPE字典和CPE与CVE之间的映射关系。
- 它为应用程序提供了一个统一的接口来获取漏洞信息,便于进行安全评估和漏洞管理。 *
- 字段说明:
- - CPEDictionary: CPE字典,包含所有正式注册的CPE条目及其详细信息
- - CPEMatchData: CPE与CVE的映射关系数据,用于查找特定CPE相关的漏洞或特定漏洞影响的CPE
- - DownloadTime: 数据下载的时间戳,便于判断数据的新鲜度 *
- 使用示例:
- ```go
- // 下载NVD数据
- options := cpe.DefaultNVDFeedOptions()
- nvdData, err := cpe.DownloadAllNVDData(options)
- if err != nil {
- log.Fatalf("下载NVD数据失败: %v", err)
- } *
- // 查找特定CPE相关的CVE
- windowsCPE, _ := cpe.ParseCpe23("cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*")
- cves := nvdData.FindCVEsForCPE(windowsCPE)
- fmt.Printf("找到%d个影响Windows 10的CVE\n", len(cves))
- for i, cveID := range cves[:5] { // 只显示前5个
- fmt.Printf("%d. %s\n", i+1, cveID)
- } *
- // 查找特定CVE影响的CPE
- cveID := "CVE-2021-44228" // Log4Shell
- affectedCPEs := nvdData.FindCPEsForCVE(cveID)
- fmt.Printf("%s影响了%d个CPE\n", cveID, len(affectedCPEs)) *
- // 获取数据下载时间
- fmt.Printf("数据更新时间: %s\n", nvdData.DownloadTime.Format(time.RFC3339))
- ``` *
- 注意事项:
- - NVD数据量较大,首次下载和处理可能需要较长时间
- - 定期更新数据以获取最新的漏洞信息
- - FindCVEsForCPE和FindCPEsForCVE方法支持模糊匹配,但可能不如精确匹配准确
func DownloadAllNVDData ¶
func DownloadAllNVDData(options *NVDFeedOptions) (*NVDCPEData, error)
*
- DownloadAllNVDData 下载并解析所有NVD数据 *
- 此函数综合获取NVD的CPE字典和CPE匹配数据,提供完整的数据集供应用程序使用。
- 它是获取全面NVD数据的便捷方法,避免分别调用多个下载函数。 *
- 参数:
- - options: NVDFeedOptions,配置下载选项,如缓存目录、HTTP客户端等 *
- 返回:
- - *NVDCPEData: 包含CPE字典和CPE匹配数据的综合结构
- - error: 发生的错误,如下载失败、解析错误等,成功时为nil *
- 使用示例:
- ```go
- options := cpe.DefaultNVDFeedOptions()
- // 设置缓存目录和最大缓存期限
- options.CacheDir = "./nvd_cache"
- options.CacheMaxAge = 7 * 24 * time.Hour // 7天 *
- // 下载所有NVD数据
- fmt.Println("开始下载NVD数据...")
- nvdData, err := cpe.DownloadAllNVDData(options)
- if err != nil {
- log.Fatalf("下载NVD数据失败: %v", err)
- }
- fmt.Println("NVD数据下载完成!") *
- // 查找特定产品的漏洞
- apacheTomcatCPE, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0.0:*:*:*:*:*:*:*")
- cves := nvdData.FindCVEsForCPE(apacheTomcatCPE)
- fmt.Printf("发现Apache Tomcat 9.0.0存在%d个漏洞\n", len(cves)) *
- // 查找指定漏洞影响的产品
- heartbleedCVE := "CVE-2014-0160"
- affectedCPEs := nvdData.FindCPEsForCVE(heartbleedCVE)
- fmt.Printf("Heartbleed漏洞(CVE-2014-0160)影响了%d个产品\n", len(affectedCPEs))
- ``` *
- 注意事项:
- - 此函数执行两次独立的下载操作,总下载时间可能较长
- - 对于生产环境,建议定期(如每周)后台更新NVD数据
- - 下载完成的数据可以持久化存储,以便多个应用程序共享使用
- - 如果只需要特定类型的数据,可以单独调用DownloadAndParseCPEDict或DownloadAndParseCPEMatch
func (*NVDCPEData) EnrichCPEWithVulnerabilityData ¶
func (data *NVDCPEData) EnrichCPEWithVulnerabilityData(cpe *CPE)
EnrichCPEWithVulnerabilityData 使用NVD数据丰富CPE信息
func (*NVDCPEData) FindCPEsForCVE ¶
func (data *NVDCPEData) FindCPEsForCVE(cveID string) []*CPE
FindCPEsForCVE 查找与特定CVE相关的所有CPE
func (*NVDCPEData) FindCVEsForCPE ¶
func (data *NVDCPEData) FindCVEsForCPE(cpe *CPE) []string
FindCVEsForCPE 查找与特定CPE相关的所有CVE
type NVDFeedOptions ¶
type NVDFeedOptions struct {
// CacheDir 缓存目录路径,用于存储下载的NVD数据Feed文件
// 默认为系统临时目录下的"cpe-cache"子目录
CacheDir string
// CacheMaxAge 缓存最大有效期(小时)
// 超过此时间后,缓存将被视为过期,需要重新下载数据
// 默认为24小时
CacheMaxAge int
// MaxConcurrentDownloads 最大并发下载数
// 控制同时进行的下载任务数量,避免过多并发请求导致资源耗尽或被服务器限制
// 默认为3
MaxConcurrentDownloads int
// ShowProgress 是否显示进度信息
// 设置为true时,下载过程中会在标准输出中显示进度信息
// 默认为true
ShowProgress bool
// HTTPClient 用户自定义的HTTP客户端
// 可配置超时时间、代理设置、传输参数等
// 默认为带有60秒超时的标准HTTP客户端
HTTPClient *http.Client
}
*
- NVDFeedOptions 定义美国国家漏洞数据库(NVD)数据Feed的下载和处理选项 *
- 该结构体包含配置NVD数据Feed获取过程的各项参数,包括缓存策略、并发控制、
- 进度显示以及HTTP客户端自定义等。这些选项影响数据获取的效率、资源消耗和用户体验。 *
- 字段说明:
- - CacheDir: 缓存目录路径,用于存储下载的NVD数据Feed文件
- - CacheMaxAge: 缓存有效期(小时),超过此时间将重新下载数据
- - MaxConcurrentDownloads: 最大并发下载数,控制同时进行的下载任务数量
- - ShowProgress: 是否显示下载进度信息
- - HTTPClient: 自定义HTTP客户端,可设置超时、代理等参数 *
- 使用示例:
- ```go
- // 使用默认选项
- options := cpe.DefaultNVDFeedOptions() *
- // 自定义选项
- customOptions := &cpe.NVDFeedOptions{
- CacheDir: "/tmp/my-nvd-cache",
- CacheMaxAge: 48, // 缓存48小时有效
- MaxConcurrentDownloads: 5, // 最多5个并发下载
- ShowProgress: true,
- HTTPClient: &http.Client{
- Timeout: 120 * time.Second, // 设置2分钟超时
- Transport: &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- MaxIdleConns: 10,
- IdleConnTimeout: 30 * time.Second,
- },
- },
- } *
- // 下载NVD数据
- data, err := cpe.DownloadAllNVDData(customOptions)
- if err != nil {
- log.Fatalf("下载NVD数据失败: %v", err)
- }
- ``` *
- 注意事项:
- - 缓存目录需要有写入权限
- - 网络环境不稳定时可能需要增加HTTP客户端的超时时间
- - 较大的并发下载数可能导致NVD服务器拒绝请求,请谨慎设置
func DefaultNVDFeedOptions ¶
func DefaultNVDFeedOptions() *NVDFeedOptions
*
- DefaultNVDFeedOptions 返回配置了合理默认值的NVD Feed下载选项 *
- 此函数创建并返回一个NVDFeedOptions结构体实例,其中所有字段都设置了适合大多数使用场景的默认值。
- 用户可以在此基础上根据需要修改特定字段,避免手动设置所有参数的麻烦。 *
- @return *NVDFeedOptions 配置了默认值的NVD Feed下载选项 *
- 默认配置:
- - CacheDir: 系统临时目录下的"cpe-cache"子目录
- - CacheMaxAge: 24小时
- - MaxConcurrentDownloads: 3
- - ShowProgress: true
- - HTTPClient: 带有60秒超时的标准HTTP客户端 *
- 使用示例:
- ```go
- // 获取默认选项
- options := cpe.DefaultNVDFeedOptions() *
- // 只修改缓存相关设置,保留其他默认值
- options.CacheDir = "/var/cache/nvd-data"
- options.CacheMaxAge = 12 // 降低缓存有效期至12小时 *
- // 使用修改后的选项下载数据
- dict, err := cpe.DownloadAndParseCPEDict(options)
- if err != nil {
- log.Fatalf("下载CPE字典失败: %v", err)
- }
- ``` *
- 注意事项:
- - 返回的是指针类型,可以直接修改其字段值
- - 默认HTTP客户端设置的超时时间为60秒,对于网络条件较差的环境可能需要增加
type ORExpression ¶
type ORExpression struct {
Expressions []Expression
}
ORExpression 表示逻辑OR表达式
func (*ORExpression) Evaluate ¶
func (e *ORExpression) Evaluate(target *CPE) bool
Evaluate 评估表达式是否匹配目标CPE
type Part ¶
type Part struct {
// 单字符简称,在CPE URI中使用,如'a'、'h'、'o'
ShortName string
// 完整名称,如'Application'、'Hardware'、'Operation System'
LongName string
// 描述信息,提供关于该组件类型的附加说明
Description string
}
*
- Part 表示CPE标识中的组件类型 *
- 在CPE规范中,Part表示产品类型,可以是应用程序、硬件或操作系统。
- 这是CPE标识的第一个组成部分,用于区分不同种类的IT产品。 *
- 属性:
- - ShortName: 单字符简称,在CPE URI中使用,如'a'、'h'、'o'
- - LongName: 完整名称,如'Application'、'Hardware'、'Operation System'
- - Description: 描述信息,提供关于该组件类型的附加说明 *
- 示例:
- ```go
- // 创建一个表示应用程序类型的CPE
- appCPE := &cpe.CPE{
- Part: *cpe.PartApplication, // 使用预定义的应用程序类型
- Vendor: cpe.Vendor("adobe"),
- ProductName: cpe.Product("acrobat_reader"),
- } *
- // 创建一个表示操作系统类型的CPE
- osCPE := &cpe.CPE{
- Part: *cpe.PartOperationSystem, // 使用预定义的操作系统类型
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- }
- ```
type Product ¶
type Product string
*
- Product 表示CPE中的产品名称组件 *
- 在CPE规范中,Product表示软件或硬件的具体产品名称,如"windows"、"office"、
- "iphone"等。Product也可以使用特殊值"*"(任意产品)或"-"(不适用)。 *
- 与其他CPE组件类似,产品名称在标准化过程中会被转换为小写,空格会被替换为下划线。 *
- 示例:
- ```go
- // 创建一个表示Microsoft Office产品的CPE
- officeCPE := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("office"),
- Version: cpe.Version("2019"),
- } *
- // 搜索特定产品
- searchCriteria := &cpe.CPE{
- ProductName: cpe.Product("office"),
- }
- options := cpe.DefaultMatchOptions()
- results := cpe.Search(cpeList, searchCriteria, options) *
- // 使用正则表达式匹配产品名
- options.UseRegex = true
- regexCriteria := &cpe.CPE{
- ProductName: cpe.Product("(word|excel|powerpoint)"),
- }
- ```
type Reference ¶
type Reference struct {
// 参考URL
URL string `json:"url" xml:"href,attr" bson:"url"`
// 参考类型,如"Vendor", "Advisory", "External"等
Type string `json:"type" xml:"type" bson:"type"`
}
*
- Reference 表示CPE项的参考信息 *
- 每个Reference包含一个指向额外信息的URL和引用类型,
- 通常指向供应商网站、文档或其他资源。
type Relation ¶
type Relation int
Relation 表示两个CPE之间的匹配关系 按照 NISTIR 7696 CPE Name Matching 规范定义
const ( // RelationDisjoint 表示两个CPE不相交,没有重叠 RelationDisjoint Relation = iota // RelationSubset 表示源CPE是目标CPE的子集 RelationSubset // RelationSuperset 表示源CPE是目标CPE的超集 RelationSuperset // RelationEqual 表示两个CPE相等 RelationEqual // RelationOverlap 表示两个CPE有重叠但不完全包含 RelationOverlap // RelationUnknown 表示关系无法确定 RelationUnknown )
func CompareWFNRelation ¶
CompareWFNRelation 根据属性比较结果确定整体关系
type SearchOptions ¶
type SearchOptions struct {
// 分页选项
Offset int
Limit int
// 排序字段
SortBy string
// 排序方向(true为升序,false为降序)
SortAscending bool
// 过滤条件
Filters map[string]interface{}
// 全文搜索查询
FullTextQuery string
// 是否包含已弃用的项
IncludeDeprecated bool
// 日期范围过滤
DateStart *time.Time
DateEnd *time.Time
// 最小CVSS评分
MinCVSS float64
// 最大CVSS评分
MaxCVSS float64
}
SearchOptions 搜索选项
func NewSearchOptions ¶
func NewSearchOptions() *SearchOptions
NewSearchOptions 创建默认搜索选项
功能描述:
- 创建并初始化带有默认值的SearchOptions对象
- 提供搜索操作的基础配置,包括分页、排序和过滤设置
- 适用于需要搜索CPE或CVE数据时简化选项创建的场景
参数:
- 无
返回值:
- *SearchOptions: 初始化后的搜索选项对象,包含以下默认值:
- Offset: 0 (从第一条记录开始)
- Limit: 100 (每页最多返回100条记录)
- SortBy: "id" (默认按ID字段排序)
- SortAscending: true (默认升序排列)
- Filters: 空map (默认无过滤条件)
- IncludeDeprecated: false (默认不包含已弃用项)
使用示例:
// 创建默认搜索选项
options := cpe.NewSearchOptions()
// 修改默认值以满足特定需求
options.Limit = 50
options.SortBy = "severity"
options.SortAscending = false
options.Filters["vendor"] = "microsoft"
// 使用选项进行搜索
results, err := storage.SearchCVE("windows", options)
线程安全:
- 此函数是无状态的,可以在并发环境中安全调用
type Storage ¶
type Storage interface {
/**
* Initialize 初始化存储
*
* 该方法用于执行存储系统所需的初始化操作,如创建目录、建立连接、初始化表结构等。
* 在使用存储系统前应首先调用此方法。
*
* @return error 初始化过程中发生的错误,成功则返回nil
*/
Initialize() error
/**
* Close 关闭存储连接
*
* 关闭与存储系统的连接,释放相关资源。使用完存储后应调用此方法。
*
* @return error 关闭过程中发生的错误,成功则返回nil
*/
Close() error
/**
* StoreCPE 存储单个CPE对象
*
* 将CPE对象持久化到存储系统中。如果存储中已存在相同ID的CPE,
* 具体行为取决于实现(可能返回错误或覆盖现有记录)。
*
* @param cpe *CPE 要存储的CPE对象
* @return error 存储过程中发生的错误,成功则返回nil
*/
StoreCPE(cpe *CPE) error
/**
* RetrieveCPE 根据ID检索CPE
*
* 从存储中检索指定ID的CPE对象。通常ID是CPE的URI表示形式。
*
* @param id string CPE的唯一标识符
* @return *CPE 检索到的CPE对象
* @return error 检索过程中发生的错误,如果未找到则返回ErrNotFound
*/
RetrieveCPE(id string) (*CPE, error)
/**
* UpdateCPE 更新CPE
*
* 更新存储中已存在的CPE对象。如果指定ID的CPE不存在,则返回错误。
*
* @param cpe *CPE 包含更新信息的CPE对象
* @return error 更新过程中发生的错误,成功则返回nil
*/
UpdateCPE(cpe *CPE) error
/**
* DeleteCPE 删除CPE
*
* 从存储中删除指定ID的CPE对象。
*
* @param id string 要删除的CPE的唯一标识符
* @return error 删除过程中发生的错误,成功则返回nil
*/
DeleteCPE(id string) error
/**
* SearchCPE 搜索CPE
*
* 根据给定的条件和选项搜索匹配的CPE对象。
*
* @param criteria *CPE 搜索条件,包含要匹配的CPE属性
* @param options *MatchOptions 匹配选项,控制匹配行为
* @return []*CPE 匹配的CPE对象列表
* @return error 搜索过程中发生的错误,成功则返回nil
*/
SearchCPE(criteria *CPE, options *MatchOptions) ([]*CPE, error)
/**
* AdvancedSearchCPE 高级搜索CPE
*
* 使用高级匹配选项搜索CPE对象,支持更复杂的匹配条件。
*
* @param criteria *CPE 搜索条件
* @param options *AdvancedMatchOptions 高级匹配选项
* @return []*CPE 匹配的CPE对象列表
* @return error 搜索过程中发生的错误,成功则返回nil
*/
AdvancedSearchCPE(criteria *CPE, options *AdvancedMatchOptions) ([]*CPE, error)
/**
* StoreCVE 存储CVE信息
*
* 将CVE引用对象持久化到存储系统中。
*
* @param cve *CVEReference 要存储的CVE引用对象
* @return error 存储过程中发生的错误,成功则返回nil
*/
StoreCVE(cve *CVEReference) error
/**
* RetrieveCVE 根据CVE ID检索CVE信息
*
* 从存储中检索指定ID的CVE引用对象。
*
* @param cveID string CVE的唯一标识符,如"CVE-2021-44228"
* @return *CVEReference 检索到的CVE引用对象
* @return error 检索过程中发生的错误,如果未找到则返回ErrNotFound
*/
RetrieveCVE(cveID string) (*CVEReference, error)
/**
* UpdateCVE 更新CVE信息
*
* 更新存储中已存在的CVE引用对象。
*
* @param cve *CVEReference 包含更新信息的CVE引用对象
* @return error 更新过程中发生的错误,成功则返回nil
*/
UpdateCVE(cve *CVEReference) error
/**
* DeleteCVE 删除CVE信息
*
* 从存储中删除指定ID的CVE引用对象。
*
* @param cveID string 要删除的CVE的唯一标识符
* @return error 删除过程中发生的错误,成功则返回nil
*/
DeleteCVE(cveID string) error
/**
* SearchCVE 搜索CVE
*
* 根据查询字符串和搜索选项搜索匹配的CVE引用对象。
*
* @param query string 搜索查询字符串
* @param options *SearchOptions 搜索选项
* @return []*CVEReference 匹配的CVE引用对象列表
* @return error 搜索过程中发生的错误,成功则返回nil
*/
SearchCVE(query string, options *SearchOptions) ([]*CVEReference, error)
/**
* FindCVEsByCPE 查找与CPE关联的CVE
*
* 查找影响指定CPE的所有CVE引用对象。
*
* @param cpe *CPE 目标CPE对象
* @return []*CVEReference 与指定CPE关联的CVE引用对象列表
* @return error 查找过程中发生的错误,成功则返回nil
*/
FindCVEsByCPE(cpe *CPE) ([]*CVEReference, error)
/**
* FindCPEsByCVE 查找与CVE关联的CPE
*
* 查找受指定CVE影响的所有CPE对象。
*
* @param cveID string CVE的唯一标识符
* @return []*CPE 与指定CVE关联的CPE对象列表
* @return error 查找过程中发生的错误,成功则返回nil
*/
FindCPEsByCVE(cveID string) ([]*CPE, error)
/**
* StoreDictionary 存储CPE字典
*
* 将CPE字典对象持久化到存储系统中。
*
* @param dict *CPEDictionary 要存储的CPE字典对象
* @return error 存储过程中发生的错误,成功则返回nil
*/
StoreDictionary(dict *CPEDictionary) error
/**
* RetrieveDictionary 检索CPE字典
*
* 从存储中检索CPE字典对象。
*
* @return *CPEDictionary 检索到的CPE字典对象
* @return error 检索过程中发生的错误,如果未找到则返回ErrNotFound
*/
RetrieveDictionary() (*CPEDictionary, error)
/**
* StoreModificationTimestamp 存储最后修改时间
*
* 记录特定键的最后修改时间戳,用于跟踪数据更新。
*
* @param key string 时间戳的键
* @param timestamp time.Time 时间戳值
* @return error 存储过程中发生的错误,成功则返回nil
*/
StoreModificationTimestamp(key string, timestamp time.Time) error
/**
* RetrieveModificationTimestamp 检索最后修改时间
*
* 检索特定键的最后修改时间戳。
*
* @param key string 时间戳的键
* @return time.Time 检索到的时间戳
* @return error 检索过程中发生的错误,如果未找到则返回ErrNotFound
*/
RetrieveModificationTimestamp(key string) (time.Time, error)
}
*
- Storage 定义了CPE和CVE数据的存储接口 *
- 该接口提供了一组统一的方法来存储、检索、更新和搜索CPE和CVE数据,
- 使得不同的存储实现(如文件存储、内存存储、数据库存储等)能够以一致的方式使用。 *
- 示例:
- ```go
- // 创建文件存储
- storage, err := cpe.NewFileStorage("/path/to/storage", true)
- if err != nil {
- log.Fatalf("无法创建存储: %v", err)
- } *
- // 初始化存储
- if err := storage.Initialize(); err != nil {
- log.Fatalf("初始化存储失败: %v", err)
- } *
- // 存储CPE
- windowsCPE := &cpe.CPE{
- Cpe23: "cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*",
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- }
- if err := storage.StoreCPE(windowsCPE); err != nil {
- log.Printf("存储CPE失败: %v", err)
- } *
- // 检索CPE
- retrievedCPE, err := storage.RetrieveCPE(windowsCPE.GetURI())
- if err != nil {
- if errors.Is(err, cpe.ErrNotFound) {
- log.Println("CPE不存在")
- } else {
- log.Printf("检索CPE失败: %v", err)
- }
- } *
- // 使用完毕后关闭存储
- defer storage.Close()
- ```
type StorageManager ¶
type StorageManager struct {
// 主存储
Primary Storage
// 缓存存储
Cache Storage
// 是否启用缓存
CacheEnabled bool
// 缓存有效期(秒)
CacheTTLSeconds int
}
StorageManager 存储管理器
func NewStorageManager ¶
func NewStorageManager(primary Storage) *StorageManager
NewStorageManager 创建存储管理器
功能描述:
- 创建并初始化StorageManager对象,用于管理CPE和CVE数据的存储操作
- 支持主存储与缓存存储的分层架构,提高数据访问效率
- 管理器会自动处理主存储和缓存存储之间的数据同步
参数:
- primary Storage: 主存储接口实现,不能为nil,作为数据的持久化存储
返回值:
- *StorageManager: 初始化后的存储管理器对象,包含以下默认设置:
- Primary: 设置为传入的主存储
- Cache: nil (默认不启用缓存)
- CacheEnabled: false (默认缓存功能关闭)
- CacheTTLSeconds: 3600 (默认缓存有效期为1小时)
异常处理:
- 如果primary参数为nil,虽然函数不会立即返回错误,但在之后使用时会导致空指针异常
使用示例:
// 创建文件存储作为主存储
fileStorage, err := cpe.NewFileStorage("/path/to/data", true)
if err != nil {
log.Fatalf("创建文件存储失败: %v", err)
}
// 初始化主存储
if err := fileStorage.Initialize(); err != nil {
log.Fatalf("初始化存储失败: %v", err)
}
// 创建存储管理器
manager := cpe.NewStorageManager(fileStorage)
// 可选: 添加内存缓存以提高性能
memCache, _ := cpe.NewMemoryStorage()
memCache.Initialize()
manager.SetCache(memCache)
性能考虑:
- 添加缓存可以显著提高频繁访问相同数据时的性能
- 默认的缓存过期时间(1小时)适用于大多数场景,对于频繁更新的数据可能需要调整
线程安全:
- StorageManager本身的初始化是线程安全的
- 实际使用的线程安全性取决于传入的Storage实现
关联方法:
- SetCache: 设置缓存存储
- GetCPE, StoreCPE: CPE数据的获取与存储
func (*StorageManager) AdvancedSearch ¶
func (sm *StorageManager) AdvancedSearch(criteria *CPE, options *AdvancedMatchOptions) ([]*CPE, error)
AdvancedSearch 高级搜索CPE对象
功能描述:
- 提供比基本Search更强大的CPE搜索功能
- 支持复杂的匹配条件和高级过滤规则
- 直接从主存储搜索,不使用缓存,确保结果完整和最新
参数:
- criteria *CPE: 搜索条件,包含要匹配的CPE属性
- 可以为nil,表示不限制搜索条件(返回所有CPE)
- 各个字段值将根据AdvancedMatchOptions中的规则进行匹配
- options *AdvancedMatchOptions: 高级匹配选项
- 不能为nil,必须提供有效的选项对象
- 包含高级匹配规则,如正则表达式匹配、版本范围匹配、逻辑组合条件等
返回值:
- []*CPE: 匹配条件的CPE对象切片
- 如果没有匹配项,返回空切片(非nil)
- error: 如果搜索过程中发生错误则返回错误
- 可能的错误类型包括:
- ErrInvalidData: 无效的搜索条件或匹配选项
- ErrStorageDisconnected: 存储后端连接问题
- 其他存储实现特定的错误
搜索行为:
- 此方法总是直接查询主存储,不使用缓存
- 查询结果不会被缓存,每次调用都会执行完整搜索
- 根据高级匹配选项,可能会执行更复杂的数据库查询或内存过滤
使用示例:
// 高级搜索: 查找所有Microsoft的产品,版本在10.0到11.0之间
criteria := &cpe.CPE{
Vendor: cpe.Vendor("microsoft"),
}
options := &cpe.AdvancedMatchOptions{
VersionRange: &cpe.VersionRange{
MinVersion: "10.0",
MaxVersion: "11.0",
Inclusive: true,
},
RegexMatch: map[string]string{
"product": "windows|office", // 产品名称匹配windows或office
},
}
results, err := manager.AdvancedSearch(criteria, options)
if err != nil {
fmt.Printf("高级搜索失败: %v\n", err)
return
}
fmt.Printf("找到 %d 个匹配项\n", len(results))
性能考虑:
- 高级搜索通常比基本搜索消耗更多资源,尤其是使用正则表达式匹配时
- 对于大型数据集,应当限制结果数量或使用更具体的搜索条件
关联方法:
- Search: 基本搜索功能,适用于简单的精确匹配
func (*StorageManager) ClearCache ¶
func (sm *StorageManager) ClearCache() error
ClearCache 清空存储管理器的所有缓存数据
功能描述:
- 清空整个缓存存储,移除所有缓存的CPE和CVE数据
- 通过重新初始化缓存存储来实现彻底清除
- 清除后,后续查询将从主存储获取最新数据
参数:
- 无
返回值:
- error: 清空缓存过程中发生的错误
- 如果缓存未启用或Cache为nil,返回nil
- 如果缓存初始化失败,返回相应错误
缓存行为:
- 如果缓存未启用(CacheEnabled为false),此方法直接返回nil
- 如果Cache为nil,此方法直接返回nil
- 缓存清空是通过重新初始化缓存实现的,比单独删除每个项更高效
使用场景:
- 在数据大规模更新后使缓存完全失效
- 当检测到缓存和主存储严重不一致时
- 作为系统维护操作的一部分
- 在缓存可能已损坏的情况下重置缓存
使用示例:
// 清空缓存
err := manager.ClearCache()
if err != nil {
fmt.Printf("清空缓存失败: %v\n", err)
return
}
fmt.Println("缓存已清空")
// 之后的所有查询都将从主存储获取数据
cpe, err := manager.GetCPE("cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*")
性能影响:
- 清空缓存后,后续的查询性能可能暂时下降,直到缓存重新填充
- 对于高访问量的系统,应在低峰期执行此操作
副作用:
- 导致所有已缓存的数据被丢弃
- 可能会触发大量的主存储查询,如果随后有大量访问请求
关联方法:
- InvalidateCache: 只使特定CPE缓存失效,而不是整个缓存
func (*StorageManager) GetCPE ¶
func (sm *StorageManager) GetCPE(id string) (*CPE, error)
GetCPE 获取CPE对象,优先从缓存获取
功能描述:
- 根据CPE ID检索对应的CPE对象
- 实现了两级存储查询策略: 如果缓存启用,优先从缓存查询,缓存未命中则从主存储查询
- 从主存储获取的数据会自动同步到缓存中,以便后续查询更快速
参数:
- id string: CPE的唯一标识符,通常为CPE 2.3格式的URI字符串
- 例如: "cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*"
- 不能为空,否则可能导致未定义行为
返回值:
- *CPE: 成功检索到的CPE对象指针
- error: 如果检索失败则返回错误
- 可能的错误类型包括:
- ErrNotFound: 指定ID的CPE不存在
- ErrStorageDisconnected: 存储后端连接问题
- 其他存储实现特定的错误
缓存行为:
- 如果缓存启用且缓存命中,直接返回缓存中的对象,不访问主存储
- 如果缓存启用但缓存未命中,从主存储获取并自动更新缓存
- 如果缓存未启用,或Cache为nil,直接从主存储获取
错误处理:
- 仅在主存储查询失败时返回错误,缓存查询失败会静默处理并继续查询主存储
- 将数据写入缓存失败不会影响返回结果,错误会被忽略
使用示例:
// 创建带缓存的存储管理器
manager := cpe.NewStorageManager(primaryStorage)
manager.SetCache(memoryCache)
// 获取Windows 10的CPE信息
windowsCPE, err := manager.GetCPE("cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*")
if err != nil {
if errors.Is(err, cpe.ErrNotFound) {
fmt.Println("CPE不存在")
} else {
fmt.Printf("获取CPE失败: %v\n", err)
}
return
}
// 使用获取到的CPE对象
fmt.Printf("产品名称: %s\n", windowsCPE.ProductName)
性能考虑:
- 缓存命中时,性能显著优于直接从主存储查询
- 频繁查询相同CPE时,建议启用缓存
关联方法:
- StoreCPE: 存储CPE并更新缓存
- InvalidateCache: 使指定CPE的缓存失效
func (*StorageManager) GetCVE ¶
func (sm *StorageManager) GetCVE(cveID string) (*CVEReference, error)
GetCVE 获取CVE引用对象,优先从缓存获取
功能描述:
- 根据CVE ID检索对应的CVE引用对象
- 实现了两级存储查询策略: 如果缓存启用,优先从缓存查询,缓存未命中则从主存储查询
- 从主存储获取的数据会自动同步到缓存中,以便后续查询更快速
参数:
- cveID string: CVE的唯一标识符,标准格式如"CVE-2021-44228"
- 不能为空,否则可能导致未定义行为
- ID格式应符合CVE命名规范(CVE-YYYY-NNNNN)
返回值:
- *CVEReference: 成功检索到的CVE引用对象指针
- error: 如果检索失败则返回错误
- 可能的错误类型包括:
- ErrNotFound: 指定ID的CVE不存在
- ErrStorageDisconnected: 存储后端连接问题
- 其他存储实现特定的错误
缓存行为:
- 如果缓存启用且缓存命中,直接返回缓存中的对象,不访问主存储
- 如果缓存启用但缓存未命中,从主存储获取并自动更新缓存
- 如果缓存未启用,或Cache为nil,直接从主存储获取
错误处理:
- 仅在主存储查询失败时返回错误,缓存查询失败会静默处理并继续查询主存储
- 将数据写入缓存失败不会影响返回结果,错误会被忽略
使用示例:
// 获取Log4Shell漏洞的CVE信息
log4jCVE, err := manager.GetCVE("CVE-2021-44228")
if err != nil {
if errors.Is(err, cpe.ErrNotFound) {
fmt.Println("CVE不存在")
} else {
fmt.Printf("获取CVE失败: %v\n", err)
}
return
}
// 使用获取到的CVE信息
fmt.Printf("漏洞描述: %s\n", log4jCVE.Description)
fmt.Printf("CVSS评分: %.1f\n", log4jCVE.CVSSScore)
性能考虑:
- 缓存命中时,性能显著优于直接从主存储查询
- 频繁查询相同CVE时,建议启用缓存
关联方法:
- FindCPEsByCVE: 查找受此CVE影响的所有CPE
- FindCVEsByCPE: 查找影响特定CPE的所有CVE
func (*StorageManager) GetStats ¶
func (sm *StorageManager) GetStats() (*StorageStats, error)
GetStats 获取存储的统计信息
功能描述:
- 收集并返回存储系统的统计数据
- 包括CPE和CVE数据的数量、字典项数量和最后更新时间等信息
- 只从主存储中获取统计信息,不涉及缓存
参数:
- 无
返回值:
- *StorageStats: 包含各种统计信息的结构体指针
- TotalCPEs: 存储中的CPE总数
- TotalCVEs: 存储中的CVE总数
- TotalDictionaryItems: 字典中的项目总数
- StorageBytes: 存储占用的字节数(部分实现可能不提供)
- LastUpdated: 最后更新时间
- error: 如果统计过程中发生错误则返回错误
- 可能的错误类型包括:
- ErrStorageDisconnected: 存储后端连接问题
- 其他存储实现特定的错误
统计过程:
- 执行全量CPE搜索,获取CPE总数
- 执行全量CVE搜索,获取CVE总数
- 获取字典并计数字典项数量
- 获取最后更新时间,如果不存在则使用当前时间
使用示例:
// 获取存储统计信息
stats, err := manager.GetStats()
if err != nil {
fmt.Printf("获取统计信息失败: %v\n", err)
return
}
// 输出统计信息
fmt.Printf("CPE总数: %d\n", stats.TotalCPEs)
fmt.Printf("CVE总数: %d\n", stats.TotalCVEs)
fmt.Printf("字典项总数: %d\n", stats.TotalDictionaryItems)
fmt.Printf("最后更新时间: %v\n", stats.LastUpdated)
性能考虑:
- 此方法可能会执行多次全量查询,在大型数据集上可能较慢
- 不建议在高频操作中调用此方法,适合用于定期监控或管理界面
实现限制:
- 目前实现仅统计总数,不提供更详细的分布信息
- StorageBytes字段在当前实现中未填充实际值
关联信息:
- StorageStats: 存储统计信息的数据结构
func (*StorageManager) InvalidateCache ¶
func (sm *StorageManager) InvalidateCache(id string)
InvalidateCache 使指定CPE的缓存失效
功能描述:
- 从缓存中删除指定ID的CPE对象
- 用于在CPE数据更新后确保缓存与主存储一致
- 静默处理删除失败的情况,不影响程序流程
参数:
- id string: 要使其缓存失效的CPE的唯一标识符
- 通常为CPE 2.3格式的URI字符串
- 如果ID在缓存中不存在,操作不会产生任何效果
返回值:
- 无
缓存行为:
- 如果缓存未启用(CacheEnabled为false),此方法不执行任何操作
- 如果Cache为nil,此方法不执行任何操作
- 缓存删除操作是尽力而为的,删除失败不会报告错误
使用场景:
- 当通过其他途径(非StorageManager)更新了CPE数据时
- 在执行UpdateCPE操作后手动调用,确保缓存一致性
- 当检测到数据不一致时主动清除缓存项
使用示例:
// 在更新CPE后,使缓存失效 cpeID := "cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*" // 通过其他方式更新了CPE数据 primaryStorage.UpdateCPE(updatedCPE) // 使对应的缓存失效,确保下次获取时能获取最新数据 manager.InvalidateCache(cpeID) // 下次调用GetCPE将从主存储获取最新数据 latestCPE, err := manager.GetCPE(cpeID)
并发安全:
- 此方法的并发安全性取决于Cache实现的DeleteCPE方法
- 对于多数实现,此方法可以安全地并发调用
关联方法:
- ClearCache: 清空整个缓存,而不是单个项
- GetCPE: 会受到此方法的影响,在缓存失效后将重新从主存储获取
func (*StorageManager) Search ¶
func (sm *StorageManager) Search(criteria *CPE, options *MatchOptions) ([]*CPE, error)
Search 搜索匹配指定条件的CPE对象
功能描述:
- 在主存储中搜索符合给定条件的CPE对象
- 根据MatchOptions中的匹配规则进行过滤
- 直接从主存储搜索,不使用缓存,确保结果完整和最新
参数:
- criteria *CPE: 搜索条件,包含要匹配的CPE属性
- 可以为nil,表示不限制搜索条件(返回所有CPE)
- 如果指定了某个字段,则匹配该字段的值
- 特殊值"*"和"-"按CPE规范处理
- options *MatchOptions: 匹配选项,控制匹配行为
- 如果为nil,将使用默认匹配选项
- 包含精确匹配/模式匹配等控制参数
返回值:
- []*CPE: 匹配条件的CPE对象切片
- 如果没有匹配项,返回空切片(非nil)
- error: 如果搜索过程中发生错误则返回错误
- 可能的错误类型包括:
- ErrStorageDisconnected: 存储后端连接问题
- 其他存储实现特定的错误
搜索行为:
- 此方法总是直接查询主存储,不使用缓存
- 查询结果不会被缓存,每次调用都会执行完整搜索
- 返回的CPE对象是数据库中对象的拷贝,修改不会影响存储
使用示例:
// 搜索所有Microsoft Windows产品的CPE
criteria := &cpe.CPE{
Vendor: cpe.Vendor("microsoft"),
ProductName: cpe.Product("windows"),
}
// 使用默认匹配选项
options := &cpe.MatchOptions{}
// 执行搜索
results, err := manager.Search(criteria, options)
if err != nil {
fmt.Printf("搜索失败: %v\n", err)
return
}
// 处理搜索结果
fmt.Printf("找到 %d 个匹配项\n", len(results))
for i, cpe := range results {
fmt.Printf("%d. %s\n", i+1, cpe.Cpe23)
}
性能考虑:
- 对于大型数据集,搜索可能需要较长时间,应考虑使用分页或限制结果数量
- 频繁执行相同搜索时,可考虑在应用层面实现结果缓存
关联方法:
- AdvancedSearch: 支持更复杂查询条件的高级搜索
- GetCPE: 根据ID直接获取单个CPE对象(支持缓存)
func (*StorageManager) SetCache ¶
func (sm *StorageManager) SetCache(cache Storage)
SetCache 设置缓存存储
功能描述:
- 为存储管理器配置缓存存储,启用缓存功能
- 设置缓存后,管理器会在读取数据时优先从缓存获取,写入数据时同时更新缓存
- 提高频繁访问相同数据时的性能,减轻主存储负担
参数:
- cache Storage: 实现Storage接口的缓存存储对象,通常为内存存储
- 如果传入nil,缓存仍会被标记为启用,但实际不会生效(建议避免传入nil)
返回值:
- 无
副作用:
- 修改管理器的Cache属性为传入的缓存存储
- 将CacheEnabled设置为true,启用缓存功能
使用示例:
// 创建存储管理器
manager := cpe.NewStorageManager(primaryStorage)
// 创建内存缓存
memCache, _ := cpe.NewMemoryStorage()
memCache.Initialize()
// 设置缓存
manager.SetCache(memCache)
// 现在管理器会使用缓存来提高性能
cpe, err := manager.GetCPE("cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*")
注意事项:
- 在调用此方法前,应确保缓存存储已经正确初始化
- 此方法不会自动同步现有数据到缓存中,缓存会在后续访问时逐渐填充
关联方法:
- GetCPE, GetCVE: 会优先从缓存获取数据
- StoreCPE: 会同时更新缓存
- InvalidateCache, ClearCache: 用于管理缓存内容
func (*StorageManager) StoreCPE ¶
func (sm *StorageManager) StoreCPE(cpe *CPE) error
StoreCPE 存储CPE对象到主存储和缓存中
功能描述:
- 将CPE对象持久化保存到主存储中
- 如果缓存已启用,同时更新缓存中的对应数据
- 确保主存储和缓存的数据一致性
参数:
- cpe *CPE: 要存储的CPE对象指针,不能为nil
- 对象必须包含有效的识别信息(如Cpe23字段)以便正确存储
- 建议在存储前使用ValidateCPE验证对象有效性
返回值:
- error: 如果存储过程中发生错误则返回具体错误
- 可能的错误类型包括:
- ErrInvalidData: CPE数据无效
- ErrDuplicate: 已存在相同ID的CPE(取决于具体存储实现)
- ErrStorageDisconnected: 存储后端连接问题
- 其他存储实现特定的错误
缓存行为:
- 如果缓存启用且Cache不为nil,成功写入主存储后会同步更新缓存
- 缓存写入失败不会影响主函数返回结果,错误会被忽略
- 即使缓存更新失败,主存储的数据仍然会成功保存
事务特性:
- 对主存储的写入具有事务性,要么完全成功要么完全失败
- 缓存更新不参与主存储的事务,缓存更新可能在主存储成功后失败
使用示例:
// 创建一个CPE对象
windowsCPE := &cpe.CPE{
Cpe23: "cpe:2.3:o:microsoft:windows:10:*:*:*:*:*:*:*",
Vendor: cpe.Vendor("microsoft"),
ProductName: cpe.Product("windows"),
Version: cpe.Version("10"),
}
// 使用存储管理器保存CPE
err := manager.StoreCPE(windowsCPE)
if err != nil {
if errors.Is(err, cpe.ErrDuplicate) {
fmt.Println("CPE已存在")
} else {
fmt.Printf("存储CPE失败: %v\n", err)
}
return
}
fmt.Println("CPE存储成功")
并发安全:
- 此方法的并发安全性取决于底层Storage实现
- 对于支持并发的Storage实现,此方法可以安全地并发调用
关联方法:
- GetCPE: 检索已存储的CPE
- ValidateCPE: 建议在存储前先验证CPE对象有效性
type StorageStats ¶
type StorageStats struct {
// CPE总数
TotalCPEs int
// CVE总数
TotalCVEs int
// 字典项总数
TotalDictionaryItems int
// 存储占用空间(字节)
StorageBytes int64
// 上次更新时间
LastUpdated time.Time
}
StorageStats 存储统计信息
type Update ¶
type Update string
*
- Update 表示CPE中产品的更新标识符 *
- 在CPE规范中,Update表示特定版本的更新或补丁级别,如"sp1"(Service Pack 1)、
- "update2"、"patch3"等。Update也可以使用特殊值"*"(任意更新)或"-"(不适用)。 *
- 与其他CPE组件类似,更新标识符在标准化过程中会被转换为小写,空格会被替换为下划线。 *
- 示例:
- ```go
- // 创建一个表示Windows 10 SP1的CPE
- windowsCPE := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- Update: cpe.Update("sp1"),
- } *
- // 搜索具有特定更新的产品
- searchCriteria := &cpe.CPE{
- ProductName: cpe.Product("windows"),
- Update: cpe.Update("sp1"),
- }
- options := cpe.DefaultMatchOptions()
- results := cpe.Search(cpeList, searchCriteria, options) *
- // 使用正则表达式匹配更新
- options.UseRegex = true
- regexCriteria := &cpe.CPE{
- Update: cpe.Update("sp[0-9]"), // 匹配sp后跟随一个数字
- }
- ```
type Vendor ¶
type Vendor string
*
- Vendor 表示CPE中的产品供应商 *
- 在CPE规范中,Vendor是指产品的制造商或提供者的名称。供应商名称通常是小写字母,
- 多词名称使用下划线连接,如"microsoft"、"adobe"、"apache_software_foundation"等。
- 供应商也可以使用特殊值"*"(任意供应商)或"-"(不适用)。 *
- 在CPE标准化过程中,供应商名称会被转换为小写,空格会被替换为下划线。 *
- 示例:
- ```go
- // 创建一个表示Microsoft产品的CPE
- microsoftCPE := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- } *
- // 在搜索条件中使用特定供应商
- searchCriteria := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- }
- options := cpe.DefaultMatchOptions()
- results := cpe.Search(cpeList, searchCriteria, options) *
- // 使用标准化函数处理供应商名称
- normalizedVendor := cpe.NormalizeComponent("Microsoft Corporation")
- // 结果为 "microsoft_corporation"
- ```
type Version ¶
type Version string
*
- Version 表示CPE中产品的版本号 *
- 在CPE规范中,Version是表示产品版本的字符串,可以包含数字、字母和特殊字符。
- 版本号可以是具体的数值如"10.0.1",也可以使用特殊值"*"(任意版本)或"-"(不适用)。 *
- 示例:
- ```go
- // 创建一个表示Windows 10的CPE
- windowsCPE := &cpe.CPE{
- Vendor: cpe.Vendor("microsoft"),
- ProductName: cpe.Product("windows"),
- Version: cpe.Version("10"),
- } *
- // 版本比较示例
- v1 := cpe.Version("10.0")
- v2 := cpe.Version("11.0")
- result := cpe.compareVersionsSimple(string(v1), string(v2)) // 返回 -1,表示v1 < v2 *
- // 在匹配选项中设置版本范围
- options := cpe.DefaultMatchOptions()
- options.VersionRange = true
- options.MinVersion = "10.0"
- options.MaxVersion = "11.0"
- ```
type VersionRange ¶
VersionRange 表示版本范围
func ParseVersionRange ¶
func ParseVersionRange(s string) (*VersionRange, error)
ParseVersionRange 解析版本范围字符串 支持格式:
- "1.0" -> 精确版本
- "1.0-2.0" -> 范围(从1.0到2.0)
- "1.0+" -> 1.0及以上
- "-2.0" -> 2.0及以下
func (*VersionRange) Contains ¶
func (vr *VersionRange) Contains(version string) bool
Contains 检查版本是否在范围内
type VulnDataSource ¶
type VulnDataSource struct {
// 数据源类型
Type DataSourceType
// 数据源名称
Name string
// 数据源描述
Description string
// 数据源URL
URL string
// 认证信息
Authentication *DataSourceAuth
// HTTP客户端
Client *http.Client
// 上次更新时间
LastUpdated time.Time
// 缓存设置
CacheSettings *CacheSettings
// 自定义选项
Options map[string]interface{}
}
VulnDataSource 表示一个漏洞数据源
func CreateGitHubDataSource ¶
func CreateGitHubDataSource(token string) *VulnDataSource
CreateGitHubDataSource 创建GitHub数据源
func CreateNVDDataSource ¶
func CreateNVDDataSource(apiKey string) *VulnDataSource
CreateNVDDataSource 创建NVD数据源
func CreateRedHatDataSource ¶
func CreateRedHatDataSource() *VulnDataSource
CreateRedHatDataSource 创建RedHat数据源
func NewVulnDataSource ¶
func NewVulnDataSource(sourceType DataSourceType, name, description, url string) *VulnDataSource
NewDataSource 创建新的数据源
func (*VulnDataSource) FetchData ¶
func (ds *VulnDataSource) FetchData(endpoint string) ([]byte, error)
FetchData 从数据源获取数据
func (*VulnDataSource) GetVulnerabilities ¶
func (ds *VulnDataSource) GetVulnerabilities(params map[string]string) ([]*CVEReference, error)
GetVulnerabilities 获取漏洞信息
func (*VulnDataSource) GetVulnerabilityById ¶
func (ds *VulnDataSource) GetVulnerabilityById(cveID string) (*CVEReference, error)
GetVulnerabilityById 根据CVE ID获取漏洞信息
func (*VulnDataSource) SearchVulnerabilitiesByCPE ¶
func (ds *VulnDataSource) SearchVulnerabilitiesByCPE(cpe *CPE) ([]*CVEReference, error)
SearchVulnerabilitiesByCPE 根据CPE查找相关漏洞
func (*VulnDataSource) SetAuthentication ¶
func (ds *VulnDataSource) SetAuthentication(auth *DataSourceAuth)
SetAuthentication 设置数据源认证信息
func (*VulnDataSource) SetCacheSettings ¶
func (ds *VulnDataSource) SetCacheSettings(cache *CacheSettings)
SetCacheSettings 设置缓存设置
type WFN ¶
type WFN struct {
Part string // 组件类型: a(应用程序)、o(操作系统)、h(硬件设备)
Vendor string // 厂商名称
Product string // 产品名称
Version string // 版本号
Update string // 更新版本
Edition string // 版本
Language string // 语言
SoftwareEdition string // 软件版本
TargetSoftware string // 目标软件
TargetHardware string // 目标硬件
Other string // 其他信息
}
WFN (Well-Formed Name) 表示CPE的规范化内部表示 WFN是CPE的内部规范表示形式,用于存储CPE各个组成部分的值 一个完整的WFN包含以下11个属性:part, vendor, product, version, update, edition, language, softwareEdition, targetSoftware, targetHardware和other
func FromCPE ¶
FromCPE 从CPE结构体创建WFN 本方法将CPE结构体转换为规范化的WFN格式,用于内部处理和比较
参数:
- cpe: CPE结构体指针,包含各个属性的值
返回值:
- *WFN: 转换后的WFN结构体指针
示例:
cpe := &CPE{
Part: *PartApplication,
Vendor: "microsoft",
ProductName: "windows",
Version: "10",
}
wfn := FromCPE(cpe)
fmt.Println(wfn.Part) // 输出: "a"
fmt.Println(wfn.Vendor) // 输出: "microsoft"
fmt.Println(wfn.Product) // 输出: "windows"
fmt.Println(wfn.Version) // 输出: "10"
func FromCPE22String ¶
FromCPE22String 从CPE 2.2格式字符串创建WFN 本方法解析CPE 2.2格式的字符串,将其转换为WFN结构体 内部实现是先将CPE 2.2转换为CPE 2.3格式,再调用FromCPE23String方法
参数:
- cpe22: 符合CPE 2.2规范的字符串,例如"cpe:/a:microsoft:windows:10"
返回值:
- *WFN: 解析成功返回WFN结构体指针
- error: 解析失败返回错误信息
示例:
wfn, err := FromCPE22String("cpe:/a:microsoft:windows:10")
if err != nil {
panic(err)
}
fmt.Println(wfn.Part) // 输出: "a"
fmt.Println(wfn.Vendor) // 输出: "microsoft"
fmt.Println(wfn.Product) // 输出: "windows"
fmt.Println(wfn.Version) // 输出: "10"
错误情况:
- 如果转换后的CPE 2.3格式字符串无效,会返回FromCPE23String传递的错误
注意:
- 该方法依赖convertCpe22ToCpe23函数,该函数将CPE 2.2格式转换为CPE 2.3格式
func FromCPE23String ¶
FromCPE23String 从CPE 2.3格式字符串创建WFN 本方法解析CPE 2.3格式的字符串,将其转换为WFN结构体
参数:
- cpe23: 符合CPE 2.3规范的字符串,例如"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*"
返回值:
- *WFN: 解析成功返回WFN结构体指针
- error: 解析失败返回错误信息
示例:
wfn, err := FromCPE23String("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
if err != nil {
panic(err)
}
fmt.Println(wfn.Part) // 输出: "a"
fmt.Println(wfn.Vendor) // 输出: "microsoft"
fmt.Println(wfn.Product) // 输出: "windows"
fmt.Println(wfn.Version) // 输出: "10"
错误情况:
- 如果字符串不以"cpe:2.3:"开头,返回格式错误
- 如果字符串不包含13个部分(以冒号分隔),返回格式错误
注意:
- 方法会自动对每个字段进行反转义处理
func (*WFN) IsIdentifierName ¶
func (*WFN) Match ¶
Match 比较两个WFN是否匹配 本方法检查当前WFN与另一个WFN是否匹配,匹配规则遵循CPE规范
参数:
- other: 另一个WFN结构体指针,用于与当前WFN比较
返回值:
- bool: 如果匹配返回true,否则返回false
示例:
wfn1 := &WFN{
Part: "a",
Vendor: "microsoft",
Product: "windows",
Version: "*", // 任意版本
}
wfn2 := &WFN{
Part: "a",
Vendor: "microsoft",
Product: "windows",
Version: "10",
}
fmt.Println(wfn1.Match(wfn2)) // 输出: true
fmt.Println(wfn2.Match(wfn1)) // 输出: true
匹配规则:
- 如果两个WFN的所有属性都匹配,则这两个WFN匹配
- 单个属性的匹配规则通过matchWFNAttribute函数定义
- 属性为"*"表示ANY,可以匹配任何值
- 如果两个属性都是"-"(NA),则它们匹配
- 其他情况要求精确匹配
func (*WFN) ToCPE ¶
ToCPE 转换WFN为CPE结构体 本方法将WFN转换回CPE结构体,用于外部使用和展示
返回值:
- *CPE: 转换后的CPE结构体指针,包含从WFN提取的所有属性值
示例:
wfn := &WFN{
Part: "a",
Vendor: "microsoft",
Product: "windows",
Version: "10",
}
cpe := wfn.ToCPE()
fmt.Println(cpe.Part.Name) // 输出: "Application"
fmt.Println(string(cpe.Vendor)) // 输出: "microsoft"
fmt.Println(cpe.Cpe23) // 输出CPE 2.3格式字符串
注意:
- 方法会自动设置CPE.Cpe23字段,生成CPE 2.3格式字符串
- 如果WFN.Part不是有效值(a/h/o),默认为应用程序(a)
func (*WFN) ToCPE22String ¶
ToCPE22String 转换WFN为CPE 2.2格式字符串 本方法将WFN结构体转换为标准的CPE 2.2格式字符串
返回值:
- string: 符合CPE 2.2规范的字符串,例如"cpe:/a:microsoft:windows:10"
示例:
wfn := &WFN{
Part: "a",
Vendor: "microsoft",
Product: "windows",
Version: "10",
Update: "sp1",
Edition: "pro",
Language: "zh-cn",
}
cpe22 := wfn.ToCPE22String()
fmt.Println(cpe22) // 输出: "cpe:/a:microsoft:windows:10:sp1:pro~zh-cn"
注意:
- CPE 2.2格式与CPE 2.3格式不完全兼容,部分字段可能无法完整表示
- 主要部分(Part, Vendor, Product, Version, Update)用冒号分隔
- 扩展属性(如Edition等)使用波浪线(~)分隔
- 方法会自动移除末尾空值的扩展属性
- 使用escapeValueForCpe22函数进行转义,转义规则与CPE 2.3不同
func (*WFN) ToCPE23String ¶
ToCPE23String 转换WFN为CPE 2.3格式字符串 本方法将WFN结构体转换为标准的CPE 2.3格式字符串
返回值:
- string: 符合CPE 2.3规范的字符串,例如"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*"
示例:
wfn := &WFN{
Part: "a",
Vendor: "microsoft",
Product: "windows",
Version: "10",
}
cpe23 := wfn.ToCPE23String()
fmt.Println(cpe23) // 输出: "cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*"
注意:
- 方法会自动对每个字段进行转义处理,使用escapeValue函数
- 所有字段之间用冒号(:)分隔,共有13部分
- 返回的字符串始终以"cpe:2.3:"开头
type XMLCPEDictionary ¶
type XMLCPEDictionary struct {
XMLName xml.Name `xml:"cpe-list"`
SchemaVersion string `xml:"schema_version,attr"`
GeneratedAt string `xml:"generated,attr"`
Items []XMLCPEItem `xml:"cpe-item"`
}
XMLCPEDictionary XML格式的CPE字典(用于解析)
type XMLCPEItem ¶
type XMLCPEItem struct {
XMLName xml.Name `xml:"cpe-item"`
Name string `xml:"name,attr"`
Deprecated string `xml:"deprecated,attr,omitempty"`
DeprecationDate string `xml:"deprecation_date,attr,omitempty"`
Title string `xml:"title"`
References []XMLReference `xml:"references>reference,omitempty"`
}
XMLCPEItem XML格式的CPE项
type XMLReference ¶
XMLReference XML格式的参考信息
Source Files
¶
- advanced_matching.go
- applicability.go
- binding.go
- builder.go
- component.go
- convenience.go
- cpe.go
- cve.go
- datasource.go
- dictionary.go
- edition.go
- errors.go
- escaping.go
- file_storage.go
- generator.go
- language.go
- matching.go
- memory_storage.go
- nvd.go
- parser_2.2.go
- parser_2.3.go
- part.go
- product.go
- search.go
- set.go
- storage.go
- update.go
- validation.go
- vendor.go
- version.go
- version_compare.go
- wfn.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
cpe
command
|
|
|
examples
|
|
|
01_basic_parsing
command
|
|
|
02_cpe_matching
command
|
|
|
03_wfn_conversion
command
|
|
|
04_version_comparison
command
|
|
|
05_applicability_language
command
|
|
|
06_cpe_sets
command
|
|
|
07_advanced_matching
command
|
|
|
08_storage
command
|
|
|
09_nvd_integration
command
|
|
|
10_cve_mapping
command
|