🔒 安全公告模型
pkg/domain 中描述 Packagist 安全公告(Security Advisories)的结构体。对应 Packagist 的 https://packagist.org/api/security-advisories/ 系列接口,由 ComposerClient.GetSecurityAdvisories / GetSecurityAdvisoriesForPackages / GetSecurityAdvisoriesSince 反序列化得到。
类型总览
| 类型 | 角色 |
|---|---|
AdvisoriesResponse | 顶层响应,按包名分组的公告映射 |
Advisory | 单条安全公告详情 |
Source | 公告来源(GitHub、NVD 等) |
🛡️ AdvisoriesResponse
安全公告响应的顶层结构。Advisories 是一个 map,键为包名,值为该包的公告列表。
go
type AdvisoriesResponse struct {
Advisories map[string][]*Advisory `json:"advisories"`
}| 字段 | 类型 | 说明 |
|---|---|---|
Advisories | map[string][]*Advisory | 安全公告映射,键为包名(如 symfony/http-foundation),值为该包的安全公告列表 |
典型 JSON 形态
json
{
"advisories": {
"symfony/http-foundation": [
{"advisoryId": "PKSA-38s9-s9dj", "packageName": "symfony/http-foundation", ...}
]
}
}🐞 Advisory
单条安全公告,包含漏洞标识、影响范围、来源与时间。
go
type Advisory struct {
AdvisoryID string `json:"advisoryId"`
PackageName string `json:"packageName"`
RemoteID string `json:"remoteId"`
Title string `json:"title"`
Link string `json:"link"`
Cve string `json:"cve"`
AffectedVersions string `json:"affectedVersions"`
Source string `json:"source"`
ReportedAt string `json:"reportedAt"`
ComposerRepository string `json:"composerRepository"`
Sources []*Source `json:"sources"`
}| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
AdvisoryID | string | Packagist 公告唯一标识 | PKSA-38s9-s9dj |
PackageName | string | 受影响的 Composer 包名 | symfony/http-foundation |
RemoteID | string | 远程系统中的 ID | CVE-2022-24894 |
Title | string | 公告标题 | HTTP Request Smuggling in Symfony HttpFoundation |
Link | string | 公告详情链接 | https://github.com/advisories/GHSA-rc93-5vf2-xh7q |
Cve | string | CVE 编号 | CVE-2022-24894 |
AffectedVersions | string | 受影响版本范围(Composer 版本约束语法) | >=5.4.0,<5.4.19|>=6.0.0,<6.0.4 |
Source | string | 来源平台 | GitHub |
ReportedAt | string | 报告时间(ISO 8601 字符串) | 2022-03-10T12:00:00Z |
ComposerRepository | string | 相关 Composer 仓库 | packagist |
Sources | []*Source | 多来源信息列表 | 见下节 |
AffectedVersions 用管道符分隔多段约束
AffectedVersions 是一段 Composer 版本约束字符串,多段之间用 | 分隔(如 >=5.4.0,<5.4.19|>=6.0.0,<6.0.4)。判断某个版本是否受影响时,应使用 Composer 的版本约束解析器,而不是简单字符串比较。
🌐 Source
公告来源信息,可能来自不同安全数据库。
go
type Source struct {
Name string `json:"name"`
RemoteID string `json:"remoteId"`
}| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
Name | string | 来源名称 | GitHub、NVD |
RemoteID | string | 来源平台中的远程 ID | GHSA-rc93-5vf2-xh7q |
🚀 示例:拉取并遍历安全公告
go
package main
import (
"fmt"
"log"
"time"
"github.com/scagogogo/composer-skills/pkg/client"
)
func main() {
c := client.NewComposerClient(60 * time.Second)
// 拉取指定包的安全公告
resp, err := c.GetSecurityAdvisoriesForPackages([]string{"symfony/http-foundation", "guzzlehttp/guzzle"})
if err != nil {
log.Fatal(err)
}
for pkg, advisories := range resp.Advisories {
fmt.Printf("=== %s (%d 条公告) ===\n", pkg, len(advisories))
for _, a := range advisories {
fmt.Printf(" [%s] %s\n", a.Cve, a.Title)
fmt.Printf(" 受影响版本: %s\n", a.AffectedVersions)
fmt.Printf(" 报告时间: %s\n", a.ReportedAt)
fmt.Printf(" 链接: %s\n", a.Link)
}
}
}按时间增量拉取
要做安全监控,用 GetSecurityAdvisoriesSince(updatedSince time.Time) 只拉取某时间点之后更新的公告,适合定时轮询场景。
📚 相关文档
- 🔙 返回 Domain 概览
- 📦 包详情字段 → package.md
- 📊 变更跟踪 → statistics.md