私有包安全需手动配置,Composer audit 识别私有包须满足:repositories 中 type 必须为 "composer" 且 URL 末尾带 /;禁用 packagist.org;packages.json 必须含标准 security-advisories 字段及完整漏洞信息。

私有包本身不安全,安全取决于你如何配置和使用它。 Composer 不会自动给私有包加锁、签名或审计——所有防护都得手动补全,漏掉任意一环,私有源就只是个“看起来私密”的下载通道。
composer.json 中 repositories 配置必须显式声明 type: "composer"
这是 audit 能识别私有包的前置门槛。写成 "type": "vcs"、"type": "package" 或直接省略,Composer 就当它不存在,连元数据都不拉,更别说查漏洞。
- 正确写法:
"type": "composer", "url": "https://satis.internal/"(注意 URL 末尾必须带/) - 错误写法:
"type": "vcs"、"url": "https://satis.internal"(缺斜杠 → 请求packages.json时 404) - 必须同级禁用官方源:
"packagist.org": false,否则私有包永远走不到 audit 流程
私有源响应的 packages.json 必须内嵌 security-advisories 字段
Composer audit 只认 FriendsOfPHP 的 schema,且只从 packages.json 里读这个字段——它不会自己爬你的 Git 提交或扫描代码。
- 字段名必须是
security-advisories(不是advisories、security或其他变体) - 每个包条目需包含完整字段:
advisory、cve、severity、version、fixed - 版本约束要精确:
">=1.0.0 不能写成"~1.2"或漏掉边界 - 若用 Satis,需在
satis.json中启用security-advisories插件并确保生成逻辑注入该字段
认证失败时 audit 静默跳过,不是报错
私有源如果需要 Basic Auth 或 Bearer Token,但 auth.json 里没配、域名不匹配、或用了 HTTP 协议,Composer 在 fetch packages.json 阶段就会失败——而 audit 不提示、不报错,直接跳过整个源。
- 验证方式:
composer config --auth --list,确认 key 和 URL host 完全一致(比如 URL 是https://repo.internal/,auth.json 里 key 必须是repo.internal) - 项目级
auth.json比全局更可靠,且务必加进.gitignore - CI 环境优先用
COMPOSER_AUTH环境变量,避免文件残留
签名验证对私有包无效,除非你自己实现
Composer 2.5+ 的 security.signature-verification 只校验 Packagist.org 上作者主动签名的包。私有源默认不参与这套机制,即使你开了全局签名检查,它也对私有包无感。
- 想让私有包也签名,必须:在私有仓库(如 Artifactory/Satis)侧启用 signing-key,生成
signature.json并随 dist 包一起提供 - 客户端还需额外配置
repositories.[name].options.signing-key指向公钥路径 - 没有这一步,
composer install只校验 hash,而 hash 本身可能被篡改(比如 lock 文件被污染)
真正容易被忽略的是:audit 报告“无漏洞”,不等于安全;它只说明“已知公开漏洞里没你”。私有包的漏洞、未公开的 CVE、甚至业务逻辑缺陷,它一概不管。把 security-advisories 塞进 packages.json 是起点,不是终点。











