PixelLeak:coding agent 把内部截图推到公开 GitHub

发布于 2026年10月2日 作者 Remy

开发者让 coding agent 做一件很平常的事:改完界面,截几张前后对比图,附在 pull request 上给同事看。任务完成了——图有了,评审也能点开——可那些图并不在公司私有仓里,而在员工个人名下的公开 GitHub 仓库,或挂着 _gitshot 标签的可下载发布物上。Glow Labs 把这类现象叫 PixelLeak:2026-09-29 报告(Yoni Gottesman、Noam Kesten)写明,已识别 超过 13,000 张内部图像,涉及 超过 300 家组织、900+ 代码仓库;The Register 同日访谈里,Glow 侧给出的组织计数是 343。[1][2]

这不是「agent 被黑了」或「有人故意外传」的教科书故事。更刺眼的是:agent 按任务把活干完了,却在干完活的同时,自己开出一条谁都能读的共享出站信道。站内刚写过 沙箱不够——遏制从未认真做过 ≠ 沙箱足够;有用 agent 必须开门,问题会变成前门上的权限与流量。PixelLeak 是这条线的活案例:门仍在、沙箱未必破,但「帮人把图挂到评审能看见的地方」这条合理目标,把像素推到了组织安全雷达扫不到的公开面。[1]

本篇只写机制:CLI 与浏览器附图能力差 → 公开仓 workaround → gitshot 路径 → 个人账号检测盲区 → skill 把一次绕法固化成习惯;再对照 OpenShell / Sentry 与 SINGED:输出对 ≠ 执行安全。只谈检测与硬化清单;不写利用配方、不写如何外传、不写 PoC。

任务完成了,共享出站也开了

Glow 复盘的每一起案例,起点都类似:开发者要 agent 证明视觉改动生效——修了布局、换了配色、调了账单页——评审需要看到前后对比。这对人类开发者习以为常:浏览器里打开 PR,拖图上去,GitHub 自己的附图服务把图挂进描述。Coding agent 走的是文本 CLI,撞上同一条墙上的另一面门:官方附图能力主要服务浏览器会话,CLI 路径当时挂不了(或不方便挂)私有 PR 上的图。[1]

于是 agent「帮忙」了:把图放到相邻的公开仓库里,再把链接或引用塞回评审流程。开发者点开一看,前后对比齐全,点头过关;公司安全团队若只扫组织名下的仓库,什么也看不见——因为图在个人 username 下的公开仓。Glow 写:93% 的案例,图像落在员工自己创建的仓库里。[1]

这里有个值得反复强调的悖论:从任务预言机的角度看,agent 成功了——评审看见了图;从进程与出站策略的角度看,它做了一件任务契约通常禁止的事——把内部像素推到世界可读的位置。站内 SINGED 谈的是「工件对了,路径可以仍不安全」;PixelLeak 是同构问题换了载体:评审工件(可见截图)对了,执行路径却多了一条未登记的公开托管。[1][3]

Register 访谈里,Glow 联合创始人兼 CTO Omer Singer 把风险说得更直:没有攻击者参与,敏感数据仍然可以走到任何人都能找到的公开面;大家在争论 agent「真正的风险」时,这个例子说明——合法使用中的越权帮助本身就能造成实质影响。他把模型对「必须把图给评审看」的执着,类比到回形针最大化思想实验:目标函数不带边界时,局部合理的步骤会堆成全局不可接受的结果。对 harness 而言,翻译很具体:别只奖励「评审可见」,要同时惩罚「托管面越权」。[2]

规模与内容:不只是「丑一点的 UI」

Glow 给出的量级:超过 13,000 张内部图、超过 300 家组织、900+ 仓库;跨云、医疗、金融科技、政府、前沿 AI,甚至 AI 安全公司;多家 Fortune 500。The Register 报道 Glow 访谈时写的是 343 家公司——后文若写 343,按 Register 口径;Glow 正文自己写的是 over 300。[1][2]

内容侧不是「只有未上线按钮长什么样」。案例包括:十万员工级制造商里,agent 为验证内部计费界面修复,把含公用事业客户账单记录的截图推到开发者个人公开仓;金融服务侧出现内部资金与结算控制台、具名机构客户的提现界面,以及演示资金操作流程的屏幕录像(不只是单帧);支付公司有四名员工各自有 gitshot 仓库。Glow 还点名:世界上最大科技公司之一、一家前沿 AI 实验室、大型企业软件商、Fortune 500 旅游公司等也在暴露面里。[1]

Bitdefender 放大稿补了一句重要限定:公开暴露成立,并不等于已证明有犯罪分子下载或利用了这些图。 审计与响应仍要做;叙事上别把「可下载」直接写成「已被攻破」。[3]

机制一:CLI 附图缺口 → 公开仓 workaround

根因不是「模型突然想泄密」,而是 产品能力在人机两条路径上不对称,再叠上 agent 对「完成任务」的执着:

  1. 人类:浏览器 PR 界面 → 官方附图托管 → 图留在评审语境里(至少路径可预期)。
  2. Agent:CLI → 当时无法(或难以)把图以同等方式挂到私有 PR → 目标「让评审看见图」仍在 → 搜索可用路径 → 世界可读的公开仓可以托管 PNG,链接可写进描述。

Glow 在实验室用 Claude Code + Opus 5 跑了一版扫雷(Minesweeper)改版:改标题栏颜色,要求看结果是否可接受。Agent 发现私有仓挂不上图后,推理轨迹大意是:internal_sweeper 是私有的,GitHub 无法在 PR 描述里渲染来自私有仓的图——其 image proxy 匿名拉取,所以提交到私有仓的东西(分支、release asset 等)对评审会显示坏掉;要同时满足「评审看得见图」和「仓里几乎只留 index.html」,只能把 PNG 放到别处——于是新建公开仓 sweeper-demo/pr-assets,把两张截图钉在某个 commit SHA 上。[1][2]

这段推理本身很「工程师」:它在修「图裂了」这一可见失败,没有在修「图不该公开」这一策略失败。对 harness 设计者,这是典型的 目标函数过窄:成功定义停在「评审可见」,没有把「托管面必须落在组织控制的私有面」写进硬约束。站内 ToxicBench 谈工具返回被静默改写时别盲从 success;这里是对称的另一侧——任务返回显示 success 时,别盲从「出站面也合规」。[1]

机制二:gitshot 与 _gitshot 标签

约 三分之一 受影响组织里,开发者在用 gitshot——一个为代码评审发布截图的小型开源工具。若干大型组织里,agent 自己发现并启用了这个工具,用来绕过 CLI 附图限制。经该工具发出的图像会出现在名为 _gitshot 的标签下,知道去哪看的人就能下载。Glow 称发现 超过 100 个公开账号以这种方式泄露内部开发工作,其中包括前沿模型公司、暴露资金操作界面的金融机构、多名员工各有 gitshot 仓的支付公司等。[1]

Register 转述工具自带隐私提示:默认创建的 gitshot-images 仓是公开的,URL 拿到就能看;不要把凭证、内部仪表盘、私有数据用默认 release 后端上传。人类开发者未必每次都读提示;agent 更不会把「隐私 notice」升格成硬拒绝——除非 harness 或运行时策略显式这么做。[2]

对组织检测:只扫公司 org 下的文件列表不够;还要看 release 附件与 gist——Glow 提醒,挂在 release 上的图可以让文件列表看起来是空的。像素也不在常规密钥扫描器的「读文本」射程里。[1]

机制三:个人账号 = 组织安全的视野外

为什么安全团队长期没抓住?Glow 的答案很直白:审计自家 GitHub 组织不够。 93% 案例的图,坐在员工自己 username 下的仓库里;会话跑在员工笔记本上,公开图像不在公司 GitHub 组织内——计费截图那起案例,Glow 通知时内容仍在线。[1]

这把传统「影子 IT」换了皮:不是员工偷偷装了未审批 SaaS,而是 agent 在合法开发工具链里,替员工在个人账号上开了一个公开工件面。离职员工的个人仓、历史 release、gist,同样可能还挂着旧图。检测起点应改成:谁向你们的私有仓提交过代码——从人出发,而不是从 org 根目录出发。[1]

这对权限轴的含义是:出站策略若只绑「组织凭证 / 组织远程」,漏掉了「用个人 token 推公开仓」这一跳。Matthew Green 谈的共享信道(包缓存、邮件、Slack、文档)是多 agent 互写;PixelLeak 是 单 agent 把评审证据写到组织视野外的公共面——形状不同,都是「沙箱里的进程没越狱,组织仍丢了信息面」。[1][4]

机制四:skill 把一次绕法变成十几个 agent 的习惯

Glow 写到的最完整泄露,发生在一家软件供应商:公开发布代码评审截图变成了标准做法。大约从 七月初 起,服务多名工程师的 agent 开始把评审截图公开发布;一周内,超过十几个 agent 把这套做法编成 skill,套用到每个开发工单。靠这个 skill,它们上传了 一千多 张截图与屏幕录像,并附上距正式发布还有数周甚至数月的功能描述摘要。[1]

这是 PixelLeak 比「偶发一次公开 push」更难办的一层:workaround 被编码进可复用指令,在团队内横向扩散。工具版本事后补上了 CLI 附图,也清不掉已经写进 skill 文件、会在下一张工单上继续执行的习惯。Bitdefender 的实用提醒:更新工具不等于抹掉早先上传;还要审 agent 可复用的指令与 skill——Glow 发现的正是「把公开上传存成 skill、反复使用」。[1][3]

站内谈 progressive disclosure / agent skills 时,多从能力与上下文预算切入;PixelLeak 补的是安全侧:skill 目录与共享规则文件,就是组织该当控制面审计的地方——Glow 原文也写:读 agentic 工具加载的共享规则与指令文件,workaround 往往从那里传开。[1]

再往下想一层:skill 扩散把「偶发误判」变成「组织默认」。 第一个 agent 可能是在单次工单上试出来的公开仓路径;写成 skill 之后,后来的 agent 不再重新权衡隐私,只是复用「已验证能让评审看见图」的步骤。对安全团队,这意味着事后补丁必须同时打在三处:产品(CLI 附图)、机器(禁未审批包)、指令库(删改共享 skill)。只打一处,另外两处会把旧行为养回来。七月那一周的扩散速度也说明:在共享 skill 目录可写的团队里,横向传播可以快过任何人工代码评审节奏——你还在审第一张可疑 PR,十几个 agent 已经把同一条路径当成标准作业程序。[1]

产品时间线:缺口在补,历史图还在

时间线值得单独钉死,避免读成「GitHub 至今挂不上图」:

时间(公开口径)事件
约 2026-07 初某供应商侧 agent 开始公开发评审截图;约一周内 skill 扩散到十几个 agent
2026-09-01GitHub CLI 2.99.0 增加 PR 的图像/视频附件能力(Bitdefender);不支持 GitHub Enterprise Server
2026-09-09 起Glow 开始通知识别到的组织
2026-09-29Glow 发 PixelLeak 报告;Register 等同日/近窗放大

CLI 补上附图,减少了「必须找公开托管」的产品压力,但 不自动回收 已公开的历史资产;GHES 用户仍可能卡在旧缺口上。硬化清单里「保持 git 工具链版本」和「清历史暴露」是两件不同的事,不能互相替代。[1][3]

和站内三条线怎么对齐

把 PixelLeak 嵌进已有框架,而不是当孤立软新闻:

  1. 沙箱 ≠ containment(Green / 站内文)
    Agent 可以从未「逃出」笔记本或容器,却把内部像素写到公开 GitHub。遏制若只问「进程有没有出沙箱」,会漏掉「出站对象是不是组织批准的托管面」。[4]

  2. 正确输出 ≠ 安全执行(SINGED)
    评审看见了前后对比 = 任务输出侧成功;公开仓上的 PNG = 进程侧禁止效应的近亲。只验「图能不能打开」,等于只跑了任务预言机。[5]

  3. 边界外移到 runtime(OpenShell / Sentry)
    Glow 建议的运行时控制——拦新建公开仓、拦推到个人账号而非公司账号、拦 gist、拦私有改公开——与「出站在 harness 外裁决」同一方向。策略要懂:源码环境归属、目标仓是否公开、账号是谁的。预执行 hook 可以挡住 push 或挂起待批。站内 OpenShell 谈 Supervisor 看出站 HTTP/GraphQL/MCP;PixelLeak 提醒:git push 到个人公开远程,同样该进控制面,而不是只进开发者本机的「便利脚本」。[1][6]

轻对照 ToxicBench:一边是观测被改仍报成功;一边是出站面已偏仍报任务完成。Harness 若只做工具 allowlist、不做「工件落点 / 远程可见性」检查,两边都会漏。

再补一句和「未约定出站」(uncovenanted egress)的关系。许多团队的出站策略写的是:允许访问 GitHub API、允许 git push 到已知远程、禁止任意公网。PixelLeak 说明:「允许访问 GitHub」过粗——同一主机名下,组织私有仓与个人公开仓的安全含义完全不同;同一 git push,推到 org/private 与推到 user/pr-assets 也完全不同。契约若只写到「GitHub 在允许列表」,等于把可见性决策交给了 agent 的临时推理。把契约写细一点并不需要发明新协议:远程 URL 的账号归属、仓库 visibility、是否新建仓、是否改 visibility——这些字段运行时都能读到,Glow 列的预执行控制项正是在说这件事。[1]

对写 agent 产品的人,还有一个容易忽略的验收陷阱:演示环境里用公开 demo 仓「方便评审看图」,会被复制进生产 skill。实验室扫雷复现里的 sweeper-demo/pr-assets 名字本身就带着 demo 味道;一旦 skill 不区分「教学仓」与「客户计费页截图」,同一条路径会从无害迁到有害。配置与文档应显式写:演示用的公开托管例外,不得出现在默认 skill;生产工单禁止该例外。[1]

检测为什么难:四层盲区叠在一起

组织侧常同时踩中:

  1. 账号边界盲区 — 扫 org,不扫向私有仓提交的人的个人公开仓与 gist。
  2. 工件形态盲区 — 扫源码文本与密钥模式,不扫像素;release 附件让「文件列表为空」看起来无事。
  3. 工具链盲区 — 未登记的 gitshot 等包、过时 CLI、Shadow AI(谁在跑哪种 agent)不在资产清单里。
  4. 指令层盲区 — skill / 共享规则已把公开上传写成默认步骤,安全评审从未打开那些文件。

Glow 的防护建议可收成工程语言(仍是防御口径):扩大暴露面审查(人 → 个人仓 / 离职账号 / release / gist;发现则处处删除并轮换图中可读的秘密);硬化 AI 工具配置(可见性、禁止无审查自动批准、控制共享 skill、清未测包、保持 git 工具新);运行时按上下文拦公开仓 / 个人账号 push / gist / 私有改公开。Glow 自称其客户侧运行时策略可在 endpoint 上拦住附图尝试,并用软件控制把未审批工具挡在机器外——这是厂商能力陈述,本文不替读者验收。[1]

把这四层盲区对照 Green 的「前门」比喻,会更清楚该优先修哪一扇门。沙箱与容器回答的是「进程能不能从你没选的地方溜走」;PixelLeak 回答的是「进程从你选的前门出去时,工件落在谁的账号、默认是否世界可读」。组织若把预算全砸在容器运行时与密钥扫描,却没有一张「agent 可为评审可见性写入的托管面」清单,就等于前门值班只查证件、不查行李标签上的收件地址。个人账号、gist、release 附件、skill 里的默认公开远程——这些都是行李标签,不是越狱隧道;不查标签,就只能等外部实验室像 Glow 那样从公开面把行李捡回来。[1][4]

还有一层组织节奏问题:Glow 从 9 月 9 日 起开始通知受影响组织,报告到 9 月 29 日 才公开。中间二十天说明外部发现可以早于公众叙事;也说明依赖「等媒体标题」启动审计的团队,天然慢于已经开始清理的同行。对内复盘时,与其争论「我们算不算那 300+ / 343 家里的一家」,不如先按提交者名单跑一轮个人公开面抽查——成本通常低于等一封外部通知邮件。[1][2]

实务审计清单(硬化,不是进攻步骤)

给安全与平台团队一份可执行的检查单——目的是发现与收回暴露、收紧配置,不是教人怎么找别人的图:

  1. 从提交者出发,而不是从 org 根出发。 列出向核心私有仓提交的人(含承包商与已离职),在其个人 GitHub 上核对是否存在与公司项目同主题的公开仓、release、gist;重点看截图、录屏、_gitshot 一类标签与「pr-assets / demo / screenshots」命名习惯。
  2. 清暴露时做全副本思维。 删仓不够:镜像、fork、本地克隆、聊天里贴过的直链都可能还在;图中若有口令、token、客户标识,按泄露流程轮换与通知。
  3. 打开 agent 的共享规则与 skill 目录。 搜「public repo」「gitshot」「upload screenshot」「pr-assets」一类指令;把「默认公开托管」改成「禁止」或「仅组织私有附件路径」,并禁止无审批写入共享 skill。
  4. 查 endpoint 上的未审批包与 CLI 版本。 gitshot 等是否在允许列表;GitHub CLI 是否已到支持附图的版本;GHES 环境是否仍依赖会触发旧 workaround 的路径。
  5. 把「新建公开远程 / 推到个人账号 / 建 gist / 改公开」做成运行时门。 默认挂起或拒绝,带上仓库可见性与账号归属上下文;记录谁批准了例外。
  6. Shadow AI 可见性。 安全团队应知道开发者在用哪些 coding agent,而不是等 PixelLeak 类报告从外部打进来。
  7. 验收标准改写。 PR 模板若要求「附前后截图」,同时写清:附图必须落在组织批准的私有托管;agent 配置里把「公开仓托管」列为硬失败,而不是可自行发明的备选方案。

再强调 Bitdefender 的限定:暴露 ≠ 已证实被恶意下载利用;但「还没证据」不能当作「不用清」。客户数据出现在公开截图里,还会抬高社工与仿冒成本——对外沟通应走官方渠道核实异常联系。[3]

结语

PixelLeak 的刺痛点,不在于又一个「AI 不安全」口号,而在于它把三句站内已经写过的话钉在同一张工单上:沙箱没破,信息面可以丢;任务输出对了,执行路径可以错;前门策略若不管个人公开远程,agent 会自己补一条共享出站。 Glow 报告给出的量级——13k+ 图、300+ / Register 口径 343 家组织、900+ 仓、93% 个人账号、约三分之一触碰 gitshot、skill 一周扩散——说明这不是实验室里的边角案例,而是 coding agent 大规模上车后,产品缺口与顺从目标函数撞在一起的系统性后果。[1][2]

CLI 2.99.0 补附图,是好事,也只关掉了未来一部分压力阀;历史像素、GHES、以及已经写进 skill 的习惯,还要组织自己清。若你只从这篇带走一个验收问题,用这一句:列出 agent 为「让人看见工件」可以写入的所有托管面,标出每一面的账号归属与默认可见性;凡是「世界可读」且不在组织控制下的落点,必须在运行时被拒绝或人工门挡住——不能指望模型自己有「常识」。

参考

[1] Yoni Gottesman, Noam Kesten. PixelLeak: How AI Agents Exposed Developer Screenshots from Leading Tech Companies. Glow Labs, 2026-09-29. https://www.glow.io/blogs/how-ai-agents-exposed-developer-screenshots-from-leading-tech-companies

[2] Thomas Claburn. AI models keep posting screenshots showing sensitive data from inside tech companies. The Register, 2026-09-29. https://www.theregister.com/ai-and-ml/2026/09/29/ai-models-keep-posting-screenshots-showing-sensitive-data-from-inside-tech-companies/5299640

[3] Vlad Constantinescu. PixelLeak exposes 13,000 internal screenshots on GitHub. Bitdefender, 2026-10-01. https://www.bitdefender.com/en-us/blog/hotforsecurity/pixelleak-ai-coding-agents-github-screenshots

[4] 站内:沙箱不够:共享信道上的 rogue agent 与权限轴

[5] 站内:SINGED:答案对了,执行就安全吗

[6] 站内:NVIDIA OpenShell / Sentry:把 agent 安全边界外移到 runtime