必须显式设repo.packagist=false才能禁用packagist主源,因composer v2+仅认该键名,repositories.packagist.org无效;关源后仅查显式声明仓库,包不在其中则报错,需手动加镜像或官方源。

禁用 Packagist 主源不能靠删 repositories 或改 URL,必须显式设 repo.packagist 为 false,否则所有自定义源都只是 fallback,供应链攻击面照旧敞开。
为什么 composer config -g repositories.packagist.org 没用?
Composer v2+ 对内置源键名校验极严:repo.packagist 是唯一合法标识符,repositories.packagist.org 会被当成普通自定义仓库,完全不接管默认行为。你执行的那条命令,只是往全局配置里加了一条无效 fallback,Packagist 仍全量索引、自动 fallback。
- 错误写法:
composer config -g repositories.packagist.org url https://mirrors.tuna.tsinghua.edu.cn/composer/→ 不影响默认源 - 正确流程:先
composer config -g repo.packagist false彻底关掉主源,再用repositories.xxx显式声明可信替代项 - 验证是否生效:
composer config -g -l | grep repositories应同时显示repo.packagist=false和你定义的repositories.*条目
repo.packagist=false 后 require 失败怎么办?
关掉默认源后,Composer 不再自动探测包归属,也不 fallback 到未声明源——它只查你 repositories 里明确列出的地址。如果 composer require vendor/name 报错,不是配置漏了,是那个包根本不在你声明的仓库里。
- 查包在哪:打开
https://packagist.org/packages/vendor/name,看右上角 “Source” 是否指向 GitHub/GitLab —— 如果是,说明它只存在于 packagist.org,必须手动加回官方源 - 临时绕过:
composer require vendor/name --repository=https://packagist.org(单次有效) - 长期方案:为该组织加镜像源,比如 VuePress 用户应配
repositories.vuepress type composer+ 对应 HTTPS 镜像 URL
全局禁用比项目级更可靠,但 CI 里容易漏掉
用 composer config --global repo.packagist false 影响所有项目,比在每个 composer.json 里加 "packagist.org": false 更彻底。但 CI 流水线里常因缓存或环境变量导致本地配置未同步。
- CI 中务必加校验步骤:
composer config --list | grep 'repo\.packagist' | grep -q 'false',失败则中断构建 - 检查环境变量:
env | grep COMPOSER_REPO_PACKAGIST,若有输出,说明它会覆盖你的repo.packagist设置 - 别依赖
repositories数组为空来判断——只要该字段存在(哪怕内容为空),Composer 就已切换到“无注册校验模式”,允许任意源拉包
真正安全的起点不是“怎么加速”,而是“谁被允许说话”。repo.packagist=false 是开关,但后续每一条 repositories.xxx 都得是你亲自审计过的可信出口——少一条,就多一个可能被投毒的入口。











