Skip to content

🔐 cli_security — 安全审计

该示例演示如何对本地 PHP 项目执行安全审计平台要求检查配置验证,覆盖 Composer CLI 在安全合规场景下的全部常用能力。

📌 示例定位

  • 学习目标:掌握 SDK 封装的安全审计、平台可用性探测、composer.json/lock 与 schema 校验、以及配置规范化流程。
  • 对应场景:CI 流水线中的安全门禁、上线前的依赖漏洞扫描、平台要求核对、配置文件合法性检查。
  • 对应 SDK 方法composer 包下的 AuditWithJSONHasVulnerabilitiesGetHighSeverityVulnerabilitiesGetAbandonedPackagesAuditWithoutDevAuditWithFormatCheckPlatformGetPHPVersionHasExtensionGetExtensionsIsPlatformAvailableValidateValidateStrictValidateComposerLockValidateSchemaNormalizeComposerJsonCheckForSecurityVulnerabilities
  • 前置条件:本机已安装 PHP 7.4+ 与 Composer 2.0+;WorkingDir 指向一个真实 PHP 项目。

📜 完整代码

go
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 门禁最简单的判定方式。

⚠️ GetHighSeverityVulnerabilitiesGetAbandonedPackages 是 SDK 在审计输出之上做的语义化筛选:前者过滤高危条目并附带 Title/Link,后者标记已废弃包,便于生成告警清单。

🎯 AuditWithoutDev 跳过 require-dev 依赖,模拟生产环境真实暴露面;AuditWithFormat("summary") 切换输出格式,可在终端友好展示。

平台要求检查(Example02PlatformCheck)

🖥️ CheckPlatform 一次性列出 PHP 版本与全部扩展的可用性,info.Available 决定显示 ✅ 还是 ❌。

🔎 GetPHPVersionHasExtension/GetExtensions 提供更细粒度的查询;IsPlatformAvailable("php", "8.1.0") 则用于在部署前精确判断目标版本是否达标。

配置验证(Example03Validation)

Validate 是默认校验,ValidateStrict 启用严格模式,二者都把 composer.json 的合法性当作部署前置条件。

🔒 ValidateComposerLock 校验锁文件与 composer.json 的一致性,ValidateSchema 校验字段格式,NormalizeComposerJson 还能自动规范化排版输出。

🚨 CheckForSecurityVulnerabilities 同时返回文本输出与布尔标志 (output, hasVuln, err),是「验证 + 漏洞」合一的复合检查,最适合作为部署最后一道关。

▶️ 运行方式

bash
# 在仓库根目录执行
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 方法

方法名所属包文档链接
AuditWithJSONcomposer/sdk/composer/methods/audit-with-json
HasVulnerabilitiescomposer/sdk/composer/methods/has-vulnerabilities
GetHighSeverityVulnerabilitiescomposer/sdk/composer/methods/get-high-severity-vulnerabilities
GetAbandonedPackagescomposer/sdk/composer/methods/get-abandoned-packages
AuditWithoutDevcomposer/sdk/composer/methods/audit-without-dev
AuditWithFormatcomposer/sdk/composer/methods/audit-with-format
CheckPlatformcomposer/sdk/composer/methods/check-platform
GetPHPVersioncomposer/sdk/composer/methods/get-php-version
HasExtensioncomposer/sdk/composer/methods/has-extension
GetExtensionscomposer/sdk/composer/methods/get-extensions
IsPlatformAvailablecomposer/sdk/composer/methods/is-platform-available
Validatecomposer/sdk/composer/methods/validate-strict
ValidateStrictcomposer/sdk/composer/methods/validate-strict
ValidateComposerLockcomposer/sdk/composer/methods/validate-composer-lock
ValidateSchemacomposer/sdk/composer/methods/validate-schema
NormalizeComposerJsoncomposer/sdk/composer/methods/normalize-composer-json
CheckForSecurityVulnerabilitiescomposer/sdk/composer/methods/check-for-security-vulnerabilities

🚀 进阶

  • 📈 CI 门禁化:把 HasVulnerabilitiesValidate 串成 pipeline 步骤,发现漏洞或校验失败即阻断部署,并配合 security_monitor 思路接入告警通道。
  • 🧾 漏洞持久化:将 AuditWithJSON 的结构化结果写入数据库,按时间维度追踪漏洞修复进度,而非仅靠终端输出。
  • 🔁 定时巡检:结合 cron 周期性调用 GetHighSeverityVulnerabilities,对新披露的 CVE 第一时间响应。
  • 🧪 平台预检:在容器构建前用 IsPlatformAvailable 校验目标运行时版本,避免上线后才发现扩展缺失。
  • 🧰 规范化流水线:将 NormalizeComposerJson 纳入提交前钩子,统一团队 composer.json 排版风格,减少无谓 diff。

基于 MIT 许可证发布