scanner.go
1 // Copyright (c) 2024-2026 Tencent Zhuque Lab. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Requirement: Any integration or derivative work must explicitly attribute 16 // Tencent Zhuque Lab (https://github.com/Tencent/AI-Infra-Guard) in its 17 // documentation or user interface, as detailed in the NOTICE file. 18 19 // Package vulstruct 漏洞扫描 20 package vulstruct 21 22 import ( 23 "fmt" 24 "strings" 25 26 "github.com/Tencent/AI-Infra-Guard/common/fingerprints/parser" 27 "gopkg.in/yaml.v3" 28 ) 29 30 // Info represents vulnerability information structure 31 // 存储漏洞信息的结构体 32 type Info struct { 33 FingerPrintName string `yaml:"name" json:"name"` // Name of the fingerprint 34 CVEName string `yaml:"cve" json:"cve"` // CVE identifier 35 Summary string `yaml:"summary" json:"summary"` // Brief summary of the vulnerability 36 Details string `yaml:"details" json:"details"` // Detailed description 37 CVSS string `yaml:"cvss" json:"cvss"` // CVSS score 38 Severity string `yaml:"severity" json:"severity"` // Severity level 39 SecurityAdvise string `yaml:"security_advise,omitempty" json:"security_advise"` // Security advisory 40 References []string `yaml:"references" json:"references"` 41 Author string `yaml:"author,omitempty" json:"author,omitempty"` 42 } 43 44 // VersionVul represents a version-based vulnerability 45 // 版本相关的漏洞结构体 46 type VersionVul struct { 47 Info Info `yaml:"info" json:"info"` // Basic vulnerability information 48 Rule string `yaml:"rule" json:"rule"` // Rule expression in string format 49 RuleCompile *parser.Rule `yaml:"-" json:"-"` // Compiled rule for evaluation 50 References []string `yaml:"references" json:"references"` // Reference links 51 } 52 53 // UnmarshalYAML implements the yaml.Unmarshaler interface 54 func (v *VersionVul) UnmarshalYAML(unmarshal func(interface{}) error) error { 55 // 定义临时结构体,Rule字段为指针类型 56 type tmpStruct struct { 57 Info Info `yaml:"info"` 58 Rule *string `yaml:"rule"` 59 References []string `yaml:"references"` 60 } 61 62 var tmp tmpStruct 63 if err := unmarshal(&tmp); err != nil { 64 return err 65 } 66 67 // 检查Rule字段是否存在 68 if tmp.Rule == nil { 69 return fmt.Errorf("missing required field 'rule'") 70 } 71 72 // 将临时结构体的值赋给原结构体 73 v.Info = tmp.Info 74 v.Rule = *tmp.Rule // 即使为空字符串也允许 75 v.References = tmp.References 76 77 return nil 78 } 79 80 // ReadVersionVul reads and parses a single vulnerability file 81 // 读取并解析单个漏洞文件 82 func ReadVersionVul(body []byte) (*VersionVul, error) { 83 // Unmarshal YAML content into VersionVul struct 84 // 将YAML内容解析到VersionVul结构体中 85 var advisory VersionVul 86 err := yaml.Unmarshal(body, &advisory) 87 if err != nil { 88 return nil, err 89 } 90 advisory.Info.Details = strings.TrimSpace(advisory.Info.Details) 91 advisory.Info.References = advisory.References 92 93 if advisory.Rule == "" { 94 advisory.RuleCompile = nil 95 return &advisory, nil 96 } 97 98 // Parse rule string into tokens 99 // 将规则字符串解析为词法单元 100 tokens, err := parser.ParseAdvisorTokens(advisory.Rule) 101 if err != nil { 102 return nil, err 103 } 104 105 // Verify token balance 106 // 验证词法单元的平衡性 107 err = parser.CheckBalance(tokens) 108 if err != nil { 109 return nil, err 110 } 111 112 // Transform tokens into DSL rule 113 // 将词法单元转换为DSL规则 114 dsl, err := parser.TransFormExp(tokens) 115 if err != nil { 116 return nil, err 117 } 118 119 advisory.RuleCompile = dsl 120 return &advisory, nil 121 }