🔐 cli_security — 安全审计
该示例演示如何对本地 PHP 项目执行安全审计、平台要求检查与配置验证,覆盖 Composer CLI 在安全合规场景下的全部常用能力。
📌 示例定位
- 学习目标:掌握 SDK 封装的安全审计、平台可用性探测、composer.json/lock 与 schema 校验、以及配置规范化流程。
- 对应场景:CI 流水线中的安全门禁、上线前的依赖漏洞扫描、平台要求核对、配置文件合法性检查。
- 对应 SDK 方法:
composer包下的AuditWithJSON、HasVulnerabilities、GetHighSeverityVulnerabilities、GetAbandonedPackages、AuditWithoutDev、AuditWithFormat、CheckPlatform、GetPHPVersion、HasExtension、GetExtensions、IsPlatformAvailable、Validate、ValidateStrict、ValidateComposerLock、ValidateSchema、NormalizeComposerJson、CheckForSecurityVulnerabilities。 - 前置条件:本机已安装 PHP 7.4+ 与 Composer 2.0+;
WorkingDir指向一个真实 PHP 项目。
📜 完整代码
package cli_security
import (
"fmt"
"log"
"github.com/scagogogo/composer-skills/pkg/composer"
)
// Example01Audit 演示如何进行安全审计
func Example01Audit() {
c, err := composer.New(composer.DefaultOptions())
if err != nil {
log.Fatalf("无法创建Composer实例: %v", err)
}
c.SetWorkingDir("/path/to/project")
// 1. 运行安全审计(JSON 结构化结果)
fmt.Println("1. 运行安全审计...")
result, err := c.AuditWithJSON()
if err != nil {
log.Printf("安全审计失败: %v", err)
} else {
fmt.Printf("发现 %d 个漏洞\n", result.Found)
}
// 2. 检查是否存在漏洞(布尔判定)
fmt.Println("\n2. 检查是否存在漏洞...")
hasVuln, err := c.HasVulnerabilities()
if err != nil {
log.Printf("检查漏洞失败: %v", err)
} else if hasVuln {
fmt.Println("⚠️ 发现安全漏洞!")
} else {
fmt.Println("✅ 未发现安全漏洞")
}
// 3. 获取高危漏洞
fmt.Println("\n3. 获取高危漏洞...")
highSeverity, err := c.GetHighSeverityVulnerabilities()
if err != nil {
log.Printf("获取高危漏洞失败: %v", err)
} else {
fmt.Printf("高危漏洞数量: %d\n", len(highSeverity))
for _, v := range highSeverity {
fmt.Printf(" - %s: %s\n", v.Title, v.Link)
}
}
// 4. 获取废弃的包
fmt.Println("\n4. 获取废弃的包...")
abandoned, err := c.GetAbandonedPackages()
if err != nil {
log.Printf("获取废弃包失败: %v", err)
} else {
fmt.Printf("废弃包数量: %d\n", len(abandoned))
for _, v := range abandoned {
fmt.Printf(" - %s: %s\n", v.Package, v.Title)
}
}
// 5. 不包含开发依赖的审计
fmt.Println("\n5. 不包含开发依赖的审计...")
output, err := c.AuditWithoutDev()
if err != nil {
log.Printf("审计失败: %v", err)
} else {
fmt.Println(output)
}
// 6. 审计(summary 格式)
fmt.Println("\n6. 审计(summary格式)...")
output, err = c.AuditWithFormat("summary")
if err != nil {
log.Printf("审计失败: %v", err)
} else {
fmt.Println(output)
}
}
// Example02PlatformCheck 演示如何检查平台要求
func Example02PlatformCheck() {
c, err := composer.New(composer.DefaultOptions())
if err != nil {
log.Fatalf("无法创建Composer实例: %v", err)
}
c.SetWorkingDir("/path/to/project")
// 1. 检查平台要求
fmt.Println("1. 检查平台要求...")
platformInfo, err := c.CheckPlatform()
if err != nil {
log.Printf("检查平台要求失败: %v", err)
} else {
for _, info := range platformInfo {
status := "✅"
if !info.Available {
status = "❌"
}
fmt.Printf(" %s %s %s\n", status, info.Name, info.Version)
}
}
// 2. 获取 PHP 版本
fmt.Println("\n2. 获取PHP版本...")
phpVersion, err := c.GetPHPVersion()
if err != nil {
log.Printf("获取PHP版本失败: %v", err)
} else {
fmt.Printf("PHP版本: %s\n", phpVersion)
}
// 3. 检查扩展是否可用
fmt.Println("\n3. 检查扩展是否可用...")
hasExt, err := c.HasExtension("mbstring")
if err != nil {
log.Printf("检查扩展失败: %v", err)
} else if hasExt {
fmt.Println("✅ mbstring 扩展已安装")
} else {
fmt.Println("❌ mbstring 扩展未安装")
}
// 4. 获取已安装的扩展列表
fmt.Println("\n4. 获取已安装的扩展列表...")
extensions, err := c.GetExtensions()
if err != nil {
log.Printf("获取扩展列表失败: %v", err)
} else {
fmt.Printf("已安装 %d 个扩展\n", len(extensions))
}
// 5. 检查特定平台是否可用
fmt.Println("\n5. 检查特定平台是否可用...")
available, err := c.IsPlatformAvailable("php", "8.1.0")
if err != nil {
log.Printf("检查平台可用性失败: %v", err)
} else if available {
fmt.Println("✅ PHP 8.1.0 可用")
} else {
fmt.Println("❌ PHP 8.1.0 不可用")
}
}
// Example03Validation 演示如何验证项目配置
func Example03Validation() {
c, err := composer.New(composer.DefaultOptions())
if err != nil {
log.Fatalf("无法创建Composer实例: %v", err)
}
c.SetWorkingDir("/path/to/project")
// 1. 验证 composer.json
fmt.Println("1. 验证composer.json...")
err = c.Validate()
if err != nil {
fmt.Printf("❌ composer.json 验证失败: %v\n", err)
} else {
fmt.Println("✅ composer.json 验证通过")
}
// 2. 严格验证
fmt.Println("\n2. 严格验证composer.json...")
output, err := c.ValidateStrict()
if err != nil {
fmt.Printf("验证失败: %v\n", err)
} else {
fmt.Println(output)
}
// 3. 验证 composer.lock
fmt.Println("\n3. 验证composer.lock...")
output, err = c.ValidateComposerLock()
if err != nil {
fmt.Printf("验证失败: %v\n", err)
} else {
fmt.Println(output)
}
// 4. 验证 schema
fmt.Println("\n4. 验证schema...")
output, err = c.ValidateSchema()
if err != nil {
fmt.Printf("验证失败: %v\n", err)
} else {
fmt.Println(output)
}
// 5. 规范化 composer.json
fmt.Println("\n5. 规范化composer.json...")
output, err = c.NormalizeComposerJson()
if err != nil {
fmt.Printf("规范化失败: %v\n", err)
} else {
fmt.Println(output)
}
// 6. 检查安全漏洞(综合判定)
fmt.Println("\n6. 检查安全漏洞...")
output, hasVuln, err := c.CheckForSecurityVulnerabilities()
if err != nil {
fmt.Printf("检查失败: %v\n", err)
} else if hasVuln {
fmt.Printf("⚠️ 发现安全漏洞:\n%s\n", output)
} else {
fmt.Println("✅ 未发现安全漏洞")
}
}🧠 代码讲解
创建实例与设置工作目录
🔧 三个函数都用 composer.New(composer.DefaultOptions()) 创建实例,再用 SetWorkingDir 指定被审计的 PHP 项目路径。所有后续命令都会在该目录下执行 composer 二进制。
安全审计(Example01Audit)
🛡️ AuditWithJSON 返回结构化结果,Found 字段直接给出漏洞数量,适合程序判定;HasVulnerabilities 进一步把结果压缩成布尔值,是 CI 门禁最简单的判定方式。
⚠️ GetHighSeverityVulnerabilities 与 GetAbandonedPackages 是 SDK 在审计输出之上做的语义化筛选:前者过滤高危条目并附带 Title/Link,后者标记已废弃包,便于生成告警清单。
🎯 AuditWithoutDev 跳过 require-dev 依赖,模拟生产环境真实暴露面;AuditWithFormat("summary") 切换输出格式,可在终端友好展示。
平台要求检查(Example02PlatformCheck)
🖥️ CheckPlatform 一次性列出 PHP 版本与全部扩展的可用性,info.Available 决定显示 ✅ 还是 ❌。
🔎 GetPHPVersion 与 HasExtension/GetExtensions 提供更细粒度的查询;IsPlatformAvailable("php", "8.1.0") 则用于在部署前精确判断目标版本是否达标。
配置验证(Example03Validation)
✅ Validate 是默认校验,ValidateStrict 启用严格模式,二者都把 composer.json 的合法性当作部署前置条件。
🔒 ValidateComposerLock 校验锁文件与 composer.json 的一致性,ValidateSchema 校验字段格式,NormalizeComposerJson 还能自动规范化排版输出。
🚨 CheckForSecurityVulnerabilities 同时返回文本输出与布尔标志 (output, hasVuln, err),是「验证 + 漏洞」合一的复合检查,最适合作为部署最后一道关。
▶️ 运行方式
# 在仓库根目录执行
cd /home/cc11001100/github/scagogogo/composer-skills
# 运行整个 cli_security 示例包(需要本机已安装 PHP 与 Composer)
go run examples/cli_security/01_audit_platform_validate.go💡 请将代码中的
/path/to/project替换为真实 PHP 项目路径;若本机未安装 Composer,SDK 会触发自动安装流程。
📚 涉及的 SDK 方法
🚀 进阶
- 📈 CI 门禁化:把
HasVulnerabilities与Validate串成 pipeline 步骤,发现漏洞或校验失败即阻断部署,并配合 security_monitor 思路接入告警通道。 - 🧾 漏洞持久化:将
AuditWithJSON的结构化结果写入数据库,按时间维度追踪漏洞修复进度,而非仅靠终端输出。 - 🔁 定时巡检:结合 cron 周期性调用
GetHighSeverityVulnerabilities,对新披露的 CVE 第一时间响应。 - 🧪 平台预检:在容器构建前用
IsPlatformAvailable校验目标运行时版本,避免上线后才发现扩展缺失。 - 🧰 规范化流水线:将
NormalizeComposerJson纳入提交前钩子,统一团队 composer.json 排版风格,减少无谓 diff。