私有仓库安全需切断代码外泄路径、阻断未授权访问、防止依赖污染;错误使用vcs类型仓库会导致git url泄露,auth.json误提交或全局配置会暴露凭证,archive未设skip-dev可能发布含调试信息的包,require-all滥用会引入未经审计依赖。

私有仓库不是“加个认证就完事”,它必须切断代码外泄路径、阻断未授权访问、防止依赖污染——否则你的核心支付模块可能正被黑客从 GitHub 镜像里悄悄下载。
私有仓库类型选错,等于把源码挂到公网目录
用 vcs 类型直接指向 Git 仓库(如 "type": "vcs", "url": "https://gitlab.com/your/payment.git")是最常见错误:Composer 会绕过认证直接 clone,且每次 install/update 都触发一次完整拉取,日志、CI 缓存、IDE 插件都可能暴露原始 URL。
正确做法是只用 composer 类型仓库,即 Satis 或 Private Packagist 这类生成静态 packages.json 的服务:
- 所有包元数据统一由私服提供,
require解析不接触原始 Git 地址 - Git 仓库本身可设为私有 + SSH-only,连 HTTPS 克隆权限都关闭
- 私服输出的
packages.json不包含敏感字段(如source中的 url),避免泄露内网地址
auth.json 放错位置,凭证就等于贴在项目门口
把 auth.json 提交进 Git、或放在项目根目录却没加 .gitignore,等于把仓库密码写在 README 里。更隐蔽的问题是:全局配置 composer config --global http-basic.repo.example.com user token 在共享服务器上会被所有用户继承。
优先级和安全边界必须理清:
- CI/CD 环境只用
COMPOSER_AUTH环境变量,值为 JSON 字符串,生命周期随构建任务销毁 - 开发机用项目级
auth.json,且必须chmod 600 auth.json并确认.gitignore包含该文件 - 绝对禁用全局配置,除非你确定整台机器只跑一个项目且无其他用户
archive 配置漏掉 skip-dev,生产环境可能打包进调试代码
Satis 的 archive 配置若没设 "skip-dev": true,默认会把 dev-master 分支打成 zip 发布——而这类分支常含 var_dump、调试钩子、未删注释,甚至硬编码测试密钥。
真实案例中,某金融后台因该配置缺失,导致上线包中残留 dd($user->token),被扫描器捕获后反向推导出 JWT 秘钥。
satis.json 中 archive 段必须显式声明:
"archive": {
"directory": "dist",
"format": "zip",
"prefix-url": "https://cdn.internal/dist/",
"skip-dev": true
}
同时确保 Git 仓库的 dev-* 分支受保护,禁止直接 push 到主干。
require-all 与精确 require 混用,会引入未经审计的依赖
"require-all": true 是 Satis 的快捷开关,但它会把所有匹配仓库的 tag/branch 全部索引进来——包括你根本没打算用的实验性组件、废弃模块、甚至测试用的 mock 包。
企业级控制必须收口:
- 禁用
require-all,改用"require": {"your-vendor/payment-core": "^2.1"}显式声明 - 每个包在 Satis 配置中单独指定
"only": ["^2.1"],限制可发布的版本范围 - 配合
composer validate检查composer.json是否含非法包名(如laravel/framework出现在私有仓库配置里)
真正的防护不在“能不能下”,而在“哪些能被看见”——Satis 输出的 packages.json 文件,就是你对外唯一暴露的依赖地图,它必须干净、精确、不可推测。











