私有源需显式声明 type: "composer" 才能参与安全校验;还需 url 末尾带斜杠、禁用 packagist.org、并在 packages.json 中手动注入兼容 friendsofphp schema 的 security-advisories 字段。

私有源必须显式声明 type: "composer" 才能参与安全校验
Composer 的 audit 命令只查 composer.lock 中已解析出的包名与版本,而这些包能否被识别为“可审计对象”,取决于它们是否来自一个被 Composer 正确识别为 composer 类型的仓库。如果你把私有源写成 "type": "vcs" 或留空,哪怕 URL 能返回 packages.json,Composer 也会跳过它——更关键的是,audit 根本不会尝试从该源拉取任何元数据做比对。
必须满足三要素:
-
repositories数组中该项的type字段值严格为"composer" -
url末尾带斜杠(如"https://satis.example.com/"),否则请求packages.json会 404 - 同级声明
"packagist.org": false,否则 Composer 默认先查官方源,你的私有包永远不进审计路径
security-advisories 元数据得手动塞进私有源响应里
FriendsOfPHP/security-advisories 是 composer audit 的唯一数据源,它不自动同步私有包漏洞。想让私有包也被扫到,你得在私有源(比如 Satis、Artifactory)返回的 packages.json 中,为每个包手动注入 security-advisories 字段,格式需完全兼容 FriendsOfPHP 的 schema:
{
"name": "acme/internal-lib",
"version": "1.2.3",
"dist": { ... },
"security-advisories": [
{
"advisory": "acme/CVE-2026-12345",
"title": "Remote code execution via unserialize()",
"cve": "CVE-2026-12345",
"severity": "critical",
"package": "acme/internal-lib",
"version": ">=1.0.0
<p>漏掉这个字段,或结构不匹配(比如用 <code>advisories</code> 而非 <code>security-advisories</code>),<code>audit</code> 就当它不存在。</p>
<h3>认证失败会导致元数据加载中断,audit 静默跳过该源</h3>
<p>私有源若需要认证(如 Basic Auth、Bearer Token),但 <code>auth.json</code> 里没配对,或者域名不一致(比如 URL 是 <code>https://repo.internal/</code>,但 <code>auth.json</code> 写的是 <code>"http-basic": {"internal.example.com": {...}}</code>),Composer 在解析 <code>packages.json</code> 阶段就会失败。此时 <code>audit</code> 不报错,也不提示“某源不可达”,而是直接忽略该仓库下所有包——你看到的“无漏洞”可能是假阴性。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3855" title="Discussion Composer"><img
src="https://img.php.cn/upload/skill/000/000/081/178981577668913.jpg" alt="Discussion Composer" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill3855" title="Discussion Composer" class="overflowclass">Discussion Composer</a>
<p class="overflowclass">围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能:
- “write my discussion”
- “help me discuss my findings”
- “how do I compare to prior studies”
- “write the limitations par</p>
</div>
<a rel="nofollow" href="/xiazai/skill3855" title="Discussion Composer" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p>验证方式很简单:</p>
- 运行
composer config --auth --list,确认 key 和 URL host 完全一致 - 手动
curl -H "Authorization: ..." https://your-private-repo.com/packages.json看能否拿到完整 JSON - 检查 CI 日志里
composer install是否出现Failed to download或401提示
别指望 audit 自动发现私有包 EOL 或 PHP 版本冲突
composer audit 只管已知 CVE,不管生命周期和兼容性。一个私有包即使已 EOL(比如停更三年、不再支持 PHP 8.2+),只要没对应 CVE 条目,audit 就显示 “No security vulnerability detected”。同样,它也不会告诉你:你锁死的 acme/internal-lib 2.1.0 要求 "php": "^7.4",而项目 config.platform.php 设的是 "8.2"——这会在部署时炸,但 audit 完全不拦。
真正要兜住这类风险,得并行跑:
-
composer validate --strict:校验platform和扩展是否存在 -
composer outdated --direct --minor-only:人工盯私有包更新节奏 - CI 中对私有包加专项检查脚本:比如
grep -r "end-of-life\|EOL" vendor/acme/internal-lib/README.md
安全校验不是开个开关就完事;私有源的元数据可信度,最终取决于你有没有能力持续维护那几行 security-advisories 字段,以及能不能让认证链不中断。










