看到一个开源项目的 README 写着Open source, audited by GLM-5.3,先别急着把它当成某种官方认证。这个表述更适合理解为:项目源码公开,作者用 GLM-5.3 做了一轮代码审计,并且愿意把这件事写进仓库。GLM-5.3 是当前开源社区里出镜率比较高的中文大模型之一,用它做代码审查并不稀奇,稀罕的是把审计过程、审计范围和复现方式一起公开。
对开发者来说,这个标签真正有价值的地方,是提供了一条可以模仿的 AI 辅助审计路径:知道怎么准备代码、怎么设计审计清单、怎么把模型输出转成可修复的问题单。这篇文章就按我实际落地时习惯的顺序,把这件事拆开讲。
1. "audited by GLM-5.3"到底代表什么:先把这个标签理解清楚
1.1 "Audited"是一个过程标签,不是一个认证结果
很多项目在 README 中加上audited by ...之后,容易被误读成“这个项目已经通过安全认证”。实际上,大模型做的审计和传统第三方安全审计是两回事。
传统审计会有明确的审计范围、审计方法、审计人员资质、漏洞编号和签名结论。而audited by GLM-5.3更多是作者自己发起的一次代码检查,模型扮演的是辅助分析角色。项目可以公开源码,作者用模型扫出问题,再经过人工确认后修复。这个动作值得鼓励,但不能因为写了一行标签,就默认项目没有安全隐患。
我看一个项目时,通常会先确认三件事:
audited的范围是什么。只审了一个核心模块,还是全部源码。- 审计时用的模型版本是什么。写
GLM-5.3比只写GLM更有追溯意义。 - 审计日期和结果在哪里。如果只有标签,没有报告、没有复现方式,那这个标签的信息量很低。
如果项目里有完整的AUDIT.md或SECURITY.md,把模型版本、提示词、文件范围、发现的问题和修复提交都列出来,这个审计的可信度会明显提高。
1.2 GLM-5.3 在代码审计中适合扮演什么角色
从实际使用效果看,GLM-5.3 这类大模型比较适合做以下几件事:
- 快速阅读陌生模块,生成代码逻辑说明。
- 检查明显的数组越界、空指针、除零、资源未释放问题。
- 分析异常路径和错误处理不完整的地方。
- 对照项目自述文件,检查实现和文档是否一致。
它不太适合直接作为最终漏洞结论的来源。模型给出的“疑似问题”必须经过人工或静态分析工具验证。比如模型说某个函数可能存在缓冲区溢出,我一般不会直接改代码,而是先找到所有调用处,看输入长度是否可控,再决定是否修复。
用一句话总结:模型的价值是把审计员从“逐行读代码”变成“带着候选问题清单去复核”,它不能替代审计员本身。
1.3 这个标签真正提供的信息量
Open source, audited by GLM-5.3真正传递的信息是“作者有审计意识”。在没有更多资料的情况下,我不会因此降低代码审查标准,但我会优先看这个项目有没有配套的审计记录。
这里有一个简单判断方式:
| 信息维度 | 只有标签 | 有完整审计记录 |
|---|---|---|
| 审计范围 | 不明确 | 明确到文件或模块 |
| 模型版本 | 可能只写 GLM | 明确 GLM-5.3 |
| 审计日期 | 无 | 有具体日期 |
| 问题列表 | 无 | 有编号、风险等级、修复提交 |
| 复现方式 | 无 | 包含提示词或脚本 |
如果项目只是加了一个标签,但没有后台细节,我建议把它当成普通开源项目看待,该做的安全评估一项都不能少。
2. 什么项目适合引入GLM-5.3辅助审计:场景、前置条件和模型选型
2.1 适合与不适合的场景
不是所有项目都需要用大模型审计。根据我自己的实践,下面几类项目收益最明显:
- 个人或小团队维护的开源库,缺少专职安全人员。
- 嵌入式中间件、驱动程序、通信协议栈,逻辑复杂但代码规模可控。
- Web 后端服务,重点检查输入校验、SQL 拼接、文件路径处理。
- 数据处理脚本,重点检查并发、异常退出和临时文件清理。
不太适合只靠模型覆盖的项目包括:密码学实现、支付系统、关键基础设施控制代码。这类项目一旦出错,后果不是“改一行代码”能解决的。模型可以作为辅助,但最终必须交给专业团队做独立审查。
另外一个需要注意的点:如果项目代码严重依赖业务上下文,比如复杂的权限体系、多租户数据隔离、秒杀活动逻辑,模型在没有完整上下文时很难发现问题。这时候要把相关文档和调用链一起提供给模型,或者先把业务规则人工整理成检查清单。
2.2 前置条件:代码、依赖、可复现环境
启动审计之前,我建议先把项目状态整理干净。一个连构建都过不去的项目,直接去审计逻辑问题,效率很低。
前置条件至少包含这几项:
- 有稳定的 Git 仓库,并能定位到具体 commit。
- 有明确的依赖清单,比如
requirements.txt、package.json、CMakeLists.txt或vcpkg.json。 - 能在干净环境完成一次构建,或者至少能完成语法检查和静态扫描。
- 开源许可证和第三方版权声明完整,避免审计过程中引入新的合规问题。
- 敏感信息已经排除,不把密码、Token、私钥提交到仓库或发送给外部模型。
在准备阶段多花半小时,后面审计会顺利很多。否则模型分析到一半,发现路径不对、依赖缺失、构建失败,很多时间就浪费在环境问题上。
2.3 完整版和轻量版怎么选:GLM-5.3 与 GLM-5.3-flash 的实际差异
网上经常看到GLM-5.3和GLM-5.3-flash一起出现。从命名和常见部署方式来看,两者大概率是完整能力版和轻量快速版的区别。完整版通常更适合复杂推理、长上下文、跨文件逻辑追踪;轻量版则更强调速度和成本,适合批量粗扫。
我在实际使用时一般这样选择:
- 单文件深度审计,比如一个 500 行以上的核心模块,使用 GLM-5.3。
- 批量扫描几十个小文件,只需要快速标记可疑点,使用 GLM-5.3-flash。
- 需要跨函数、跨文件追踪数据流时,优先使用完整版。
- 只需要解释报错含义、给出构建命令建议时,轻量版够用。
这里要注意一个常见误区:不是把所有文件一次性塞给模型就能得到“完整审计”。大模型有上下文窗口限制,输入过长会丢失细节,输出质量会明显下降。我一般会把仓库按模块拆成多个文件,每次审计一个模块,把相关头文件、调用关系和配置片段作为上下文提供给模型。
3. 把一次AI辅助审计跑通:准备、提示词、执行和留痕
3.1 先确定审计范围和代码快照
开始前,先明确这次审计到底审什么。我通常会在仓库根目录创建一个audit/目录,把下面这些信息固定下来:
audit/ 01-snapshot/ 2025-06-01_commit_hash.zip 02-prompts/ round1-general.md round2-module-core.md 03-outputs/ round1-result.md round2-result.md 04-report/ audit-report.md代码快照要锁定到具体 commit,而不是“最新的代码”。因为审计完发现问题、提交修复后,需要能够对比前后差异。如果没有快照,过几天连自己都不知道当时看的是哪一版。
清楚记录范围也有助于避免重复审计。比如这次只审src/core和src/net,下次再审src/ui,这样每次报告都可以对账。
3.2 搭建一个可复现的审计环境
大模型审计看起来不需要安装额外工具,但要保证“可复现”,还是需要把环境固定下来。我的做法是在audit/下写一个README,记录:
- 操作系统和 CPU/GPU 信息。
- 模型入口是 API、命令行还是本地部署。
- 模型版本名称,例如 GLM-5.3 或 GLM-5.3-flash。
- 提示词文件列表。
- 使用的静态分析工具及版本。
如果项目较小,直接用一个 Python 脚本把目标文件读取出来,再拼接提示词发送给模型,也是一个不错的选择。脚本本身不需要复杂,重点是把“输入”和“输出”都落盘。
3.3 审计清单和提示词模板
没有审计清单就去找模型聊天,容易得到一堆泛泛而谈的建议。我通常会把风险类别写清楚,让模型按固定格式输出。
第一轮粗扫的提示词模板如下:
你现在是一名开源代码审计助手。请审查以下文件,重点关注: 1. 缓冲区边界与数组越界风险。 2. 动态内存分配失败后的处理。 3. 并发访问与可重入性。 4. 错误码是否被正确传播。 5. 外部输入是否被充分校验。 文件路径:src/example.c 代码内容: [把代码粘贴到这里] 请按问题列表输出,每条包含: - 问题位置 - 问题描述 - 风险级别:高/中/低 - 修复建议模型输出后,我建议不要直接复制到报告里。先做一轮人工分类:哪些是真实问题,哪些是模型误报,哪些是风格建议。因为大模型有时会把“代码写得不优雅”误判成安全问题,也会漏掉只有在真实调用链中才会出现的越界。
3.4 执行顺序:先单文件,再跨文件,再专项
我习惯把审计拆成三轮,而不是一次性完成。
第一轮,逐个文件粗扫。目标是快速找到明显的可疑点。这一轮用模型最合适,因为大模型读代码速度快,几个文件下来不会太累。
第二轮,跨文件追踪。把可疑点的调用关系找出来,查看调用方是否有鉴权、长度校验、状态判断。模型在单文件模式下看不到全局上下文,这一轮需要人工组织输入。
第三轮,专项检查。针对项目类型做专项审计,比如加密存储项目重点看密钥管理,网络项目重点看报文解析和超时处理,嵌入式项目重点看中断共享资源和内存对齐。
三轮之间隔离好产出物。第二轮和第三轮发现的新问题,不要和第一轮混在一起,方便后面统计误报率。
3.5 保留审计记录
审计记录至少应该包括:模型版本、日期、代码范围、提示词、原始输出、人工复核结论。这样别人看到audited by GLM-5.3时可以按记录重跑一遍,而不是只能相信一个标签。
如果没有复现能力,审计结果的价值会打折扣。因为安全问题本身就是会发生变化的事情,依赖升级、接口变化、编译器差异都会影响结果。
4. 实战:ARM嵌入式开源项目的头文件缺失排查
4.1 看到一个具体报错先别急着分析代码
很多人拿到一个错误就去问模型,这个做法本身没问题,但前提是要把错误分成“构建环境问题”和“业务逻辑问题”两类。
比如下面这种报错:
error: #5: cannot open source input file "arm_acle.h": no such file or directory这看起来像代码缺失,实际上更常见的是工具链或 CMSIS 路径配置不对。arm_acle.h是 ARM C Language Extensions 相关头文件,通常由编译器或嵌入式 SDK 提供。它不是你自己在项目里写出来的文件,所以不能靠“补一个同名头文件”来修复。
我在遇到这类报错时,会先确认编译工具链有没有正确安装,再检查头文件搜索路径是否包含了 CMSIS 和芯片厂商 SDK 目录。
4.2 排查链路一:头文件搜索路径
arm_acle.h找不到,优先怀疑编译器 include 路径没有配置正确。不同项目使用的构建方式不同,排查顺序可以这样走:
| 检查点 | 说明 |
|---|---|
| 工具链是否安装完整 | 曾经出现过只安装了编译器,但缺少 device 头文件的情况 |
| 项目是否引用了 CMSIS | arm_acle.h通常来自 ARM 编译器或相关扩展库 |
| include 路径是否包含 SDK 头文件目录 | 检查 CMake 里的INCLUDE_DIRECTORIES或 Keil 项目的 Include Paths |
| 路径是否写错 | 注意大小写、正反斜杠、绝对路径和相对路径 |
| 缓存是否旧 | 增量构建偶尔会使用旧配置,清掉 build 目录重新 cmake 一次 |
常见命令示例,以 CMake 项目为例:
rm -rf build cmake -B build -DCMAKE_TOOLCHAIN_FILE=path/to/toolchain.cmake cmake --build build如果重新构建还是同样的报错,再看工具链自带目录里是否有这个头文件。可以用下面的命令快速确认:
find /你的工具链安装目录 -name "arm_acle.h"有时候工具链里没有这个文件,是因为没有安装对应的 library 组件,而不是路径写错。此时需要的操作是补齐工具链组件,而不是在项目里伪造一个同名头文件。
4.3 排查链路二:core_cm0plus.h 缺失
另一个典型报错是:
fatal error[pe1696]: cannot open source file "core_cm0plus.h"这个文件是 CMSIS 核心头文件,专门针对 Cortex-M0+ 内核。它来自 CMSIS 库,一般由芯片厂商 SDK 或独立 CMSIS 包提供。
我见过几类常见原因:
- 项目使用 Keil MDK,但 CMSIS 包没有安装到对应版本。
- 直接从某个仓库拷贝了
core_cm0plus.h,但文件和当前工具链版本不匹配。 - 项目是用 GCC 工具链编译,但 include 路径没有包含 CMSIS 的
Core/Include目录。 - 没有配置设备宏定义,例如缺少
STM32F0xx或NRF52相关的DEVICE宏,导致头文件选择逻辑走错分支。
对于这类头文件缺失,最稳妥的办法是使用芯片厂商官方 SDK 里带的那份 CMSIS,而不是随便从网上下载同名文件。CMSIS 版本和芯片型号相关,版本不匹配会带来更隐蔽的寄存器定义错误。
4.4 拿GLM-5.3分析这个问题时,应该给它什么输入
如果想让 GLM-5.3 辅助排查,不要只抛一句“arm_acle.h 找不到”。模型没有你的文件系统视角,需要把现场信息整理清楚。
一个比较有效的提示词结构是:
我在编译一个 ARM 嵌入式开源项目时遇到头文件缺失错误。 完整报错: error: #5: cannot open source input file "arm_acle.h": no such file or directory 构建系统:CMake / Keil MDK / IAR 工具链:GCC ARM 版本或 ARMCC 版本 目录结构: test-project/ CMakeLists.txt src/main.c lib/cmsis/ lib/device/ 最近改动:我刚刚从 v1.0 切换到 v1.1 分支。 已经尝试:清理 build 目录并重新构建,仍然报错。 请列出可能的排查步骤,以及每个步骤的判断标准。这样模型给出的回答更容易落到实地。它虽然不能直接读取你的目录,但可以根据这些信息推断优先级:先确认 CMSIS 是否存在,再检查 include 路径,再检查宏定义。
需要留意的是,模型给出的排查顺序不一定 100% 适用于你的项目。它可能假设头文件应该在某个位置,但你的 SDK 目录结构不同。遇到这种情况,以工程实际为准。
5. 审计结果怎么落地:分级、修复、复验与开源合规
5.1 问题分级与处置
审计结果出来之后,先分级再处理。我一般按下面的标准分:
| 风险级别 | 判断标准 | 处理建议 |
|---|---|---|
| 高 | 可被外部输入直接触发,可能导致崩溃、越界或提权 | 立即修复,编写对应测试用例 |
| 中 | 需要特定条件触发,或影响错误处理、资源释放 | 安排到最近迭代修复 |
| 低 | 代码风格、可读性、注释缺失、重复逻辑 | 可以合并进重构任务 |
| 误报 | 模型描述的问题在真实调用链中不存在 | 记录到审计报告,不修改代码 |
模型输出里出现“高风险”词汇时,先不要慌。很多高等级风险其实需要真实输入和控制流才能确认。比如模型说“这里存在整数溢出风险”,那就需要看外部用户能否控制参与计算的数值,以及结果是否会影响内存访问或权限判断。
如果无法确认,我建议写一个最小复现用例,用单测或本地脚本验证。能稳定复现的问题,才进入修复阶段。
5.2 修复后的回归验证
修复时不要直接在main分支上改。先新建一个修复分支,把修改提交到独立分支上,然后在新的场景里重新构建和测试。这样万一修复引入新问题,还可以对照差异。
修复完成后,还需要做一次“回归审计”。我喜欢用和第一轮完全相同的提示词和文件快照,再跑一遍 GLM-5.3,看是否还有类似告警。这一步很有意义,因为修复一个问题可能引入新的问题,尤其是缓冲区、状态机、并发控制相关代码。
回归审计的产出物也放进audit/目录,这样整个审计过程是闭环的:原始问题、修复提交、二次结果都有记录。
5.3 开源合规:许可证、第三方代码边界和审计声明
开源项目的审计不只包括代码漏洞,还要检查许可证和第三方代码边界。很多开发者把注意力放在内存安全上,却忽略了项目里夹带的一段代码可能违反许可证要求。
审计时至少检查这些点:
- 每一个第三方库是否有明确的许可证声明。
- 项目自己的许可证和依赖库许可证是否兼容。
- 是否保留原作者的版权声明。
- 代码中是否存在从其他仓库复制但不带来源说明的片段。
- 文档中是否列出了依赖清单和许可证信息。
如果用 GLM-5.3 辅助识别许可证,可以让它分析某个头文件或源码片段可能来自什么许可证体系,但最终判断要靠人。模型对许可证的理解有时候会过度简化,尤其是遇到 BSD、MIT、Apache 2.0 混用的时候。
审计声明本身也要写得克制。不要在 README 里写“已经完成全部安全审计,项目无漏洞”。更稳妥的写法是:
本项目在 2025-06-01 使用 GLM-5.3 对 src/core 模块进行了代码审计。 审计方式、提示词和结果记录在 audit/ 目录。 审计结果不构成安全保证,重大变更后需要重新审计。这样既展示了可靠性,也不会给使用者造成错误的安全预期。
6. 客观看待AI审计的边界,以及我的实践底线
6.1 模型的输出只能作为候选,不能作为结论
大模型在代码审计中最大的优势是快,但最大的风险是“自信地犯错”。它可能把一段安全代码误报为高风险,也可能漏掉真正的问题。
我遇到过一次模型建议修改一个比较简单的字符串拼接逻辑,说可能有格式化字符串漏洞。但实际代码里参数完全可控,不存在用户输入路径。如果直接按模型建议改,反而会把代码变复杂,还引入新的可读性问题。
所以我的底线是:模型输出的每一条结论,都要能落到“代码位置 + 触发条件 + 影响范围”三个要素上。凑不齐这三个要素,就不算有效问题。
6.2 保密、数据权限与公网模型
使用在线模型审计代码时,一定要先想清楚数据能不能出去。开源项目本身是公开的,问题不大;但企业内部项目、未发布版本、包含接口密钥或客户信息的代码,不能直接粘贴到外部模型。
安全做法是:
- 先把代码做脱敏处理,用
xxx替换真实密钥、域名、IP。 - 只发送必要的函数和片段,不要发送整个数据库结构。
- 如果有条件,部署本地可运行的模型或私有化 API 服务。
- 审计记录中不包含敏感数据,即使报告本身要公开。
这个边界比功能选型更重要。审计工具给项目带来价值的前提,是不能引入新的数据泄露风险。
6.3 审计记录要能重放
一个值得信任的audited by GLM-5.3标签,背后应该有一份可以重放的记录。重放的意思是:别人拿到同样的代码快照、同样的提示词、同样的模型版本,能得到大致一样的输出。
为了做到这一点,需要把整个流程脚本化。哪怕只是一个简单脚本,也能减少手工粘贴带来的差异。比如用 Python 读取代码文件,拼接提示词,调用模型接口,把输出保存到 Markdown 文件。这样每一次审计都能追溯到原始输入。
如果项目只是随手把几个文件扔进模型聊天框,然后把聊天记录截图放进仓库,我不认为这是完整的审计。它可能有用,但缺少系统性。
我的建议是:从一开始就把审计当成一项工程任务来管理。范围、环境、提示词、输出、人工复核、修复提交,每一步都留痕。这样audited by GLM-5.3才会从一个标签变成一份可信的工程记录,而不是一句宣传语。