导语:只需点一下链接,攻击者就能拿到你GitHub账号的完整控制权——读写所有私有仓库。最近,安全研究员Ammaraskar(阿马拉斯塔卡尔)公布了这一VSCode漏洞的完整技术细节,向我们展示了攻击者如何利用WebView的消息传递机制,绕过安全边界,悄无声息地窃取你的GitHub令牌。
一、背景:github.dev的强大与风险
你知道GitHub有一个很酷的功能叫github.dev吗?
只要访问一个有权限的仓库,把URL里的github.com改成github.dev,或者点击下拉菜单里的这个选项:

你就会进入一个轻量级的VSCode界面——完全运行在浏览器里。

这个浏览器版的VSCode功能相当强大:可以查看仓库里的所有文件(包括私有仓库),可以发送Pull Request,甚至可以直接提交代码。
实现这些功能的方法是:当你访问github.dev时,它会向GitHub发送一个POST请求,换取一个OAuth令牌,允许github.dev代表你与GitHub交互。关键问题在于,这个令牌的作用域不是仅限于你当前访问的仓库,而是对你有权限的所有其他仓库都有完全的访问权限。
这意味着,如果攻击者能拿到这个令牌,他就能读写你的所有私有仓库。
而github.dev运行着VSCode上百万行TypeScript代码库的几乎全部代码,自然成了安全研究人员挖掘漏洞的绝佳目标。
二、VSCode WebView的安全模型
VSCode是一款基于Electron的桌面应用,在桌面版中执行任意JavaScript就等同于完整的远程代码执行。因此VSCode实现了一套沙箱机制,其中最核心的就是WebView。
WebView通过与VSCode主窗口建立不同的源(origin),从而确保在其中执行的任何JavaScript都完全隔离。WebView用于Markdown预览、Jupyter Notebook编辑等功能。
Jupyter Notebook的单元格输出会渲染到一个源为vscode-webview://...的中,而主Electron窗口的源则是vscode-file://...。这意味着,即使用户在Notebook中使用了HTML显示功能或JavaScript交互组件,VSCode核心程序也受到保护,无法直接访问这些内容。
很好,这让我们能渲染内容了。但静态内容太无聊,怎么实现Markdown预览时实时显示当前高亮的源代码行这样的功能呢?

这种跨域策略在保障安全的同时,也阻止了主编辑器窗口与vscode-webview://...框架中的DOM进行交互。毕竟没人希望有人利用与Google页面交互,从而窃取Cookie或改变网站行为。
要实现跨域通信,唯一的方式是让两个不同源的网页通过Window.postMessage() API进行协作。
三、漏洞:键盘事件的中继攻击
WebView的安全边界大致是这样的:

但在用户界面上,WebView就嵌入在这个窗口里。用户期望在里面点击链接、按快捷键等基本操作都能正常工作。
因此,VSCode通过消息传递机制实现了许多基本功能。说到键盘快捷键,细心的读者可能已经注意到问题了。
和大多数跨域操作一样,浏览器在两个框架之间提供了相当程度的隔离。简单说就是:如果你的页面通过iframe嵌入了Google的登录页,你肯定不希望黑客能在你的页面上给iframe添加键盘监听器,窃取用户在Google上输入的所有内容。
根据这些信息,现在试试点击VSCode WebView内部,然后按Ctrl+Shift+P调出命令面板。
哦耶,居然成功了。等一下。不对。糟了。
为了避免用户点击WebView内部时键盘快捷键失效这种糟糕体验,VSCode默认的WebView消息处理程序会注册一个did-keydown事件。当加载WebView时,会运行以下代码:
contentWindow.addEventListener('keydown', handleInnerKeydown);const handleInnerKeydown = (e) => { hostMessaging.postMessage('did-keydown', { key: e.key, keyCode: e.keyCode, code: e.code, shiftKey: e.shiftKey, altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, repeat: e.repeat });};
也就是说,WebView会把键盘事件冒泡上传,让VSCode主窗口把这些事件当作用户自己的键盘事件来处理。
但是——没有任何措施能阻止WebView中不受信任的脚本冒充用户,按下一堆按键。
比如,我们可以调出命令面板,然后执行危险命令,比如安装一个攻击者控制的扩展。我们只需要发送正确的事件来模拟按键操作:
- Ctrl+Shift+P
- 输入扩展安装命令
- Enter
但事情没那么简单。虽然我们可以发送与这个序列对应的keydown事件,但浏览器不会将其视为用户手动输入。VSCode会弹出命令面板,但我们的事件实际上并不会将文本输入到面板中——因为命令面板使用的是HTML标签,没有监听keydown事件来逐字处理输入。
不过我们可以在命令面板中上下滚动(按上下箭头键)或选择命令(按Enter),但无法输入任意文本。
幸运的是,VSCode内置了大量默认键盘快捷键,全部直接监听keydown事件。经过一番摸索,最简单的方法是利用”通知:接受通知主要操作”功能。这个快捷键Ctrl+Shift+A会点击VSCode中最后弹出的通知的主要按钮。
我们接受哪种通知?

VSCode有一个功能,允许工作区通过在.vscode/extensions.json文件中添加扩展推荐,这样访问仓库时就会弹出推荐安装扩展的通知。
然后用Ctrl+Shift+A来接受安装扩展的通知,获取完整代码执行权限?就这么简单?
当然不是。从1.97版本开始,VSCode引入了新的发布者信任系统,首次从新发布者安装扩展时会弹出信任对话框:

虽然我们可以用Tab键在按钮之间导航,但按Enter选择”信任发布者并安装”按钮是不可能的,因为它只监听按钮上的keydown事件,而不是整个窗口的事件。
我们可以利用VSCode的另一个功能——本地工作区扩展。只要你身处受信任的工作区(github.dev/web工作区始终受信任),就可以直接从.vscode/extensions目录安装扩展。这种方式安装的扩展会跳过发布者信任检查。
但事情没那么顺利——这样做会导致Content Security Policy(CSP)错误,因为加载扩展的工作线程期望扩展来自vscode-cdn.net。本地工作区扩展没有很好地配合Web版VSCode测试。

不过这只是个小小的障碍。扩展可以在package.json中向VSCode贡献额外的键盘快捷键。既然我们能可靠地触发键盘快捷键,就可以添加一个快捷键来调用我们想要的VSCode命令——比如安装扩展同时跳过发布者信任检查。
最终,我们需要的仓库要包含一个Jupyter notebook和一个本地工作区扩展。Jupyter notebook可以通过包含以下内容的Markdown单元格执行少量JavaScript:
![图9–利用VSCode漏洞一键窃取GitHub Token–seo优化_前端开发_渗透技术 图9–利用VSCode漏洞一键窃取GitHub Token–seo优化_前端开发_渗透技术]()
完整攻击链如下:
- 等待VSCode弹出询问是否安装推荐扩展的通知
- 发送Ctrl+Shift+A按键事件,接受通知
- 等待扩展安装并激活,完成自定义快捷键设置
- 发送Ctrl+F1按键事件,触发安装我们选定的扩展
四、PoC与自保护
详细技术分析看完了,来看看概念验证(PoC)。最大胆的读者可以直接访问这个仓库体验:
https://github.dev/ammaraskar/github-dev-token-steal-poc/blob/main/README.ipynb
这会直接启动github.dev编辑器,打开notebook,你会看到JavaScript payload正在运行的状态信息。

payload运行后,新安装的扩展会获取你的GitHub API令牌,然后查询私有仓库列表,最后在一个信息框中打印出来。

如果你运行了PoC,记得清除github.dev数据,或者至少卸载这个概念验证扩展,否则它会一直跟着你访问所有github.dev页面。
这个漏洞也存在于VSCode桌面版,只是利用难度更高——需要说服受害者克隆仓库并在Notebook中打开带有payload的文件。当然,如果你在WebView中还有另一个XSS漏洞能让受害者打开,那你就能在他们电脑上实现完整的远程代码执行。
如何保护自己
幸运的是,如果你从未使用过github.dev,访问网站时会弹出一个对话框让你确认。这个功能是后来才有的,因为VSCode的GitHub插件发生了变化。

这意味着如果你清除github.dev的Cookie和本地站点数据,当有人尝试对你发起这种攻击时,你可以采取行动并离开页面。
强烈建议清除github.dev的站点数据。在Chrome中,可以点击URL栏中的小图标,然后点击Cookie和网站数据 > 管理设备上的站点数据。

然后删除所有带有垃圾桶图标的域名数据:

遗憾的是,如果你之前已经用过github.dev且没有清除浏览器的本地存储,你就完全中招了。github.dev没有任何CSRF令牌之类的保护,任何互联网上的链接都可以把你重定向到攻击页面。
五、VSCode做得好的地方与完全公开披露
VSCode不仅仅依赖,还使用了纵深防御措施,比如严格的Content Security Policy(CSP)和使用DOMPurify来清理渲染的Markdown内容,这些措施在这里发挥了重要作用。
如果有人能在扩展页面的Markdown预览中找到执行任意JavaScript的方法,你可以想象这个漏洞会造成多大的影响。但是由于使用了script-src 'none'策略,这种情况被有效地扼杀了。

至于为何选择完全公开披露,简单说:上次与MSRC(微软安全响应中心)打交道报告VSCode漏洞的经历非常糟糕——他们悄无声息地修复了我指出的漏洞,没有给予任何credit,还把这个漏洞标记为”没有安全影响”。所以以后发现的任何VSCode安全漏洞都会进行完全公开披露。
原文出处:1-Click GitHub Token Stealing via a VSCode Bug – Ammar’s Blog原文链接:https://blog.ammaraskar.com/github-token-stealing/图片版权:本文所有图片版权归原文作者Ammaraskar所有

seo优化_前端开发_渗透技术










