如何从 ChatGPT 和其他大型语言模型中移除“隐藏代码”

CometAPI
AnnaNov 21, 2025
如何从 ChatGPT 和其他大型语言模型中移除“隐藏代码”

随着大型语言模型(LLM)越来越多地生成可运行代码,并被集成到开发流水线与代理(agent)栈中,隐藏或恶意指令的风险正在上升——无论这些指令是嵌入在模型输出中、通过网页或第三方插件注入,还是在模型训练过程中引入——一旦这些代码被执行,可能导致不安全行为。

据开发者社区的用户报告,一名软件开发者在使用CursorAI IDE、借助Gemini 3生成的代码时遭遇灾难性数据丢失——约800GB 的文件被删除,包括CursorAI 应用本体。随着开发者愈发依赖 LLM 进行代码生成,未审查或不安全脚本带来的后果愈发严重。

因此,了解如何检测并移除由 LLM 生成的危险代码至关重要。

在 ChatGPT 与 LLM 语境中,“隐藏代码”是什么?

人们所说的“隐藏代码”指什么?

“隐藏代码”是开发者的统称,用来描述 LLM 摄取或输出的文本(或文件)中包含的任何嵌入式指令或可执行内容,包括:

  • 嵌入在用户内容中的“提示式指令”(例如,被隐藏在 PDF 中的“忽略先前指令……”)。
  • 用于隐藏标记或打破分词假设的不可见字符或零宽字符。
  • 编码载荷(base64、URL 编码、以及嵌入在图像或文档中的隐写内容)。
  • 隐藏的 HTML/JS 或脚本块,可能被下游渲染器解释执行。
  • 指导检索系统或模型的元数据或注释(文件注释、PDF 隐藏层等)。
  • 由于使用危险 API 而产生的隐式行为(例如 evalexecsubprocess 或网络/系统调用),即使并非显式恶意。
  • 由提示注入导致的指令,使模型生成包含隐藏命令或类似后门逻辑的代码,因为攻击者对提示或上下文进行了工程化处理。

当目标是改变模型行为时,这些攻击向量通常被称为“提示注入”或“间接提示注入”。安全社区现已将提示注入视为核心 LLM 漏洞,OWASP 也已将其正式归类为 LLM 风险类别。

这与常规恶意软件或 XSS 有何不同?

差异在于语义层:提示注入针对的是模型的指令跟随行为,而非宿主操作系统或浏览器渲染引擎本身。尽管如此,最终在网页渲染器中执行的隐藏 HTML 或脚本仍然是可执行攻击(类似 XSS);语义层与执行层都必须防御。行业领袖与研究者将提示注入称为“前沿安全挑战”,并持续发布缓解策略。

为什么 LLM 会产生隐藏或危险代码?

模型行为、训练数据与指令上下文

LLM 被训练为根据上下文与指令生成看似合理的续写。如果上下文包含对抗性线索,或用户请求模型编写具有强大副作用的代码,模型可能输出包含微妙或主动危险行为的代码。

LLM 会生成看似合理但不安全的代码

LLM 优化的目标是流畅与有用,而非在具有破坏性副作用的情境下确保安全。当被要求“清理”时,它可能轻易生成简洁的 rm -rf /path/to/dirshutil.rmtree(),而且由于响应通常自信措辞,用户可能在缺乏足够审查的情况下复制并运行。这种“自信型幻觉”问题使看似无害的请求也会变得危险。

混淆工作流的自动化

威胁行为者正在通过串联 LLM 调用来自动化代码混淆:一个模型生成载荷,另一个模型重写以规避特征检测,依此类推。2025 年的行业威胁报告与厂商分析已将这种“AI 辅助混淆”记录为新兴技术。

如何检测模型输出中的隐藏代码?

快速排查清单

  1. 扫描不可见/异常 Unicode(零宽连接符、零宽空格、字节序标记、非 ASCII 同形字符)。
  2. 运行静态分析/AST 解析,识别强权限 API 的使用(evalexecsubprocessos.system、反射调用)。
  3. 查找编码载荷(base64、十六进制大块、重复的长字符串或压缩内容)。
  4. 检查混淆模式(字符串拼接构造 API 名称、字符运算、chr() 链)。
  5. 使用语义分析确认代码是否实际执行 I/O、联网或文件系统修改。

静态模式检测(快速、第一道防线)

  • 具备语言感知的解析与代码规范检查。立即将生成内容区分为代码块与正文。运行格式化与 linter(Black/Prettier、pylint、eslint)。规则应标记 evalexecrm -rf、原始子进程调用或动态构造的 shell 管道。
  • 基于标记与字符串的模式扫描器。搜索高风险标记与模式:sudo、如 /home/C:\ 等绝对路径,rm -rfshutil.rmtreesubprocess.Popen、内联 base64 大块、无法直观理解的长字符串、以及切换解释器上下文的 shebang。
  • 密钥扫描与来源校验。检测硬编码凭据、指向不受信注册表的 URL、或动态从任意来源拉取包的代码。

静态分析能快速捕获许多显而易见的问题,并且作为 CI 关卡运行成本低。

语义与上下文检测(更深入)

  • 意图分析。使用次级模型或规则引擎对生成代码的意图进行分类:是“读”“写”“删除”“网络”“安装”?凡是被归类为删除/写入,应升级处理。
  • 数据流分析。分析代码,检测未经验证或来源于用户输入的路径是否可达破坏性 API。例如,若某变量源自 LLM 输出或远程文件,并被拼接进 shell 命令,应当标记。
  • 溯源关联。保留对话、系统提示与上下文页面的完整记录。若可疑输出与某个外部文档或插件调用相关,则可能指示提示注入或被污染的上下文。

动态与行为检测(最可靠)

  • 带监控的沙箱执行。在严格受限、一次性的环境中执行生成代码,禁用网络、禁止挂载主机,并使用系统调用过滤(seccomp)。监控文件系统活动、网络调用尝试、进程生成与异常 I/O。
  • 金丝雀测试。在真实数据运行前,先对合成目录(包含哨兵文件)运行;监控删除或覆盖行为。
  • 行为启发式。关注遍历父目录的循环、无深度检查的递归操作、或可能伤害大量文件的重命名模式(例如反复写入同一文件名)。
    动态分析是检测仅在运行时触发、延时或经过混淆的载荷的唯一方式。

在执行 LLM 输出前,应如何移除或中和隐藏代码?

防御性移除 vs. 改变语义

在“移除隐藏代码”时有两个目标:

  1. 净化(Sanitization)——移除显然非代码或可疑内容(不可见 Unicode、零宽字符、附加的 base64 载荷)。这不应改变本意的良性逻辑。
  2. 中和(Neutralization)——对于任何会执行或调用外部服务的代码,在验证前将这些调用禁用或替换为无操作。

始终优先考虑“中和 + 复核”,而非盲删:随意删除代码会导致破损或意外行为。应以显式、记录在案的桩替换可疑结构,安全失败(抛出异常或返回安全默认值)。

第 1 步——将生成代码视为不受信数据

切勿直接执行来自 ChatGPT(或任何 LLM)的代码,必须先经过移除与加固流水线。该流水线应由策略强制并在 CI/CD 中自动化。

第 2 步——提取并规范化代码

  • 文本规范化并移除零宽字符:剔除 U+200B、U+200C、U+200D、U+FEFF 等零宽/格式化码点。将移除内容记录到审计日志。此步骤能消除许多用于视觉隐匿的“隐藏”编码。
  • 剥离所有非代码上下文:移除叙述性文字、隐藏注释与任何 HTML/Markdown 包裹。用语言格式化器(Black、Prettier)将代码转换为规范形式,归一化混淆空白或控制字符。
  • 拒绝或隔离包含以下结构的代码:动态 eval、原始子进程调用(os.systemsubprocess.Popen)、内联 base64 载荷并解码执行、或试图切换解释器上下文的嵌入式 #! 指令。文本规范化并移除零宽字符
    剔除 U+200B、U+200C、U+200D、U+FEFF 等零宽/格式化码点。将移除内容记录到审计日志。此步骤能消除许多用于视觉隐匿的“隐藏”编码。

第 3 步——解析为 AST 并替换高风险节点

将代码解析为 AST,查找调用动态执行(如 exec)或以编程方式构造函数名的节点。用安全桩替换它们,使其抛出“已阻止不安全动态行为”的受控异常。生成基于 AST 的净化源码供审查。运行安全模式检查(为你的环境定制 semgrep 规则)。匹配命中处进行标记与中和。

第 4 步——静态加固与重写

  • 自动重写:通过自动净化器将危险调用替换为安全封装器——例如用受控沙盒执行器替换 os.system()/subprocess,强制超时与网络阻断。
  • 能力门控:修改或移除 API 密钥、令牌或对高权限端点的调用;在本地测试中改为使用模拟适配器。防止意外包含机密或 URL。
  • 依赖重写:阻止代码内动态执行 pip/npm 安装。要求依赖在你的制品库中声明并审批。

第 5 步——在高强度沙箱中运行

  • 一次性容器/微型虚机:在无网络、无法访问主机凭据、文件系统访问受限的容器/虚机中执行。可使用 gVisor、Firecracker 或专用的一次性执行服务。若必须访问 I/O,通过策略执行的代理进行。
  • 系统调用过滤与 seccomp:限制允许的系统调用。阻止临时目录之外的文件写入。
  • 资源/时间限制:设置 CPU/内存/时间限制,避免逻辑炸弹无限运行。

沙箱执行与监控常能发现静态检查遗漏的载荷。行业指南与近期白皮书均建议将沙箱作为核心缓解手段。

你的流水线应包含哪些自动化工具与规则?

推荐工具链组件

  • Unicode 净化模块(自研或现有库)。必须记录被规范化的字符。
  • 各目标语言的解析器与 AST 分析器(Python 的 asttyped-ast,JavaScript 解析器,Java 解析器)。
  • 静态分析/SAST:Bandit(Python)、Semgrep(多语言、可定制)、带安全插件的 ESLint。
  • 熵与解码启发式:检测 base64/hex/gzip 并路由至检查。
  • 沙箱运行时:极简容器,使用严格的 seccomp/AppArmor 配置,或在禁用系统调用的语言级解释器中运行。
  • 策略执行器:决定允许的模块、端点与安全 API 封装器。
  • 审计追踪:不可篡改的日志,记录原始输出、净化后输出、差异与决策。

示例 semgrep 模式(概念)

使用简短而保守的规则标记危险函数的使用。例如:

  • 标记 evalexecFunction 构造器(JS)、动态导入或字符串构造的 API 名称。
  • 标记超出允许列表的网络调用(例如未知主机上的 requests.get)。
  • 标记对敏感路径(如 /etc、系统文件夹)的写入,以及进程生成。

(将这些作为组织的配置项,并随时间逐步收紧。)

有哪些实用的净化代码片段(安全示例)?

以下是可复用的、非危险的防御性示例。它们是净化与检测片段——而非利用性指令。

示例:移除零宽字符(Python,防御性)

import re
ZERO_WIDTH_RE = re.compile(r'')
def strip_zero_width(s: str) -> str:
    cleaned = ZERO_WIDTH_RE.sub('', s)
    return cleaned

这会移除攻击者常用来在可见文本中隐藏代码的字符。务必记录移除了哪些内容,并将其纳入审计轨迹。

示例:解析并检查 AST(Python,概念)

import ast

def has_dynamic_exec(source: str) -> bool:
    tree = ast.parse(source)
    for node in ast.walk(tree):
        if isinstance(node, ast.Call):
            if getattr(node.func, 'id', '') in ('eval', 'exec',):
                return True
        if isinstance(node, ast.Attribute):
            if getattr(node, 'attr', '') in ('popen', 'system'):
                return True
    return False

如果 has_dynamic_exec 返回 True,请勿运行代码;而应将动态节点替换为安全桩并要求人工复核。

注:这些示例具有防御性质。不要移除日志、审计或人工复核环节。

结语:始终将 LLM 输出视为不受信代码

语言模型是强大的生产力工具——它们可以产出优雅代码、加速草稿与自动化日常工作。但一旦触及执行边界,安全规则就改变了:模型输出必须被视为不受信任的工件。过去 18–30 个月里提示注入、后门研究与真实世界披露的结合清楚地表明:风险面正在扩大,并将持续演化。

结合解析、静态分析、沙箱化动态测试、治理与持续红队的实用防御,足以阻止大多数攻击。但团队也必须投入组织层面的控制:最小权限、来源可溯与“默认需要验证”的文化。行业正在构建工具与框架以简化这些模式;在此期间,采用上述清单可降低隐藏载荷漏网的概率。

开发者可以通过 CometAPI 访问最新的 LLM API,例如Claude Sonnet 4.5 APIGemini 3 Pro Preview等;最新模型版本会与官网保持同步更新。开始之前,可在Playground探索模型能力,并查阅API guide获取详细指引。访问前请确保已登录 CometAPI 并获取 API key。CometAPI提供远低于官网的价格,帮助你完成集成。

Ready to Go?→ Sign up for CometAPI today

如果你想获取更多 AI 技巧、指南与新闻,欢迎关注我们的 VKXDiscord

阅读更多

一个 API 中超 500 个模型

最高 20% 折扣