
🎯 学 gstack 的双模型安全审计系统:不是跑一个 SAST 工具看报告,而是结合 OWASP(OWASP:开放Web应用安全项目)Top 10(攻击者视角的十大威胁)和 STRIDE(STRIDE:微软威胁建模框架,设计视角的六大威胁模型),对代码库进行系统性安全审查——从注入攻击、认证绕过到加密误用,覆盖 Web 应用最可能被攻破的每一个面。 ⏱️ 预计时间:35 分钟
💡 新手提示:如果你刚接触安全审计,先理解两个核心视角——OWASP 关注"攻击者怎么打进来",STRIDE 关注"系统设计哪里脆弱"。两者就像防盗门检查清单加上房屋结构安全检查,互补而非替代。
§1 课程概览
[!note]- 白话小课堂 安全审计不是跑工具看报告。OWASP Top 10 告诉你攻击者从哪打进来——注入、认证绕过、加密失败这些"最常见的十种攻击方式"。STRIDE 告诉你系统设计哪里脆弱——欺诈、篡改、信息泄露这些"设计层面的六大威胁"。
两者结合才叫"全面":就像你家既要检查门锁有没有坏(OWASP),也要检查墙体结构有没有裂缝(STRIDE)。cso 的输出不是给你看一个"高危漏洞列表"就完事了,而是告诉你攻击者会怎么利用、影响多大、怎么修、修完怎么验证。
这节课学完你能拿到一套完整的安全审计模板——从 OWASP 十个维度逐一排查,从 STRIDE 六个角度威胁建模,最后输出一份工程团队能直接执行的修复清单。
[!quote]- 📖 原Skill精要 技能名称:cso 核心功能:首席安全官模式。基础设施优先安全审计:密钥考古学、依赖供应链、CI/CD 管道安全、LLM/AI 安全、Skill 供应链扫描,外加 OWASP Top 10、STRIDE 威胁建模和主动验证。两种模式:daily(零噪音,8/10 置信度关口)和 comprehensive(月度深度扫描,2/10 标准)。跨审计趋势追踪。 所属体系:gstack 虚拟工程团队 协作关系:与 [[L6-15-PR代码审查|review]] 的安全专家互补——cso 是全仓库深度安全审计,review specialist 是 PR 级安全检查
§2 为什么需要双模型审计?
OWASP Top 10 + STRIDE = 全面安全视图
单一审计方法的问题: → SAST 工具:大量误报,不看上下文 → 手动渗透测试:只覆盖测试者想到的攻击面 → 合规检查:只关注"是否满足标准"而非"是否真的安全"
双模型互补: OWASP Top 10(攻击者视角): → "外面的人怎么打进来?" → 基于真实世界的攻击数据(OWASP 社区统计) → 覆盖最常见的 10 种攻击向量
STRIDE(设计者视角): → "系统设计的每个环节有什么威胁?" → 基于微软的威胁建模方法论 → 覆盖 6 种威胁类别: Spoofing(欺诈) Tampering(篡改) Repudiation(否认) Information Disclosure(信息泄露) Denial of Service(拒绝服务) Elevation of Privilege(权限提升)
两者结合 = 攻击者知道怎么打 + 设计者知道哪里有弱点
§3 OWASP Top 10 深度审查
十大威胁的审查清单
A01: Broken Access Control(访问控制缺陷)
→ IDOR(不安全的直接对象引用):/api/users/123 → 改成 124 能看别人的? → 垂直越权:普通用户直接访问 admin 端点 → 水平越权:用户 A 通过改参数访问用户 B 的数据 → CORS 配置过宽:Access-Control-Allow-Origin: * → 检查方法:遍历所有端点,检查是否有 auth middleware
A02: Cryptographic Failures(加密失败)
→ 敏感数据明文传输(HTTP 而非 HTTPS) → 弱加密算法(MD5、SHA1 用于密码存储) → 可预测的随机数(Math.random() 用于 token 生成) → 硬编码的密钥/盐值 → 检查方法:Grep 搜索 crypto、password、secret、key、token、jwt
A03: Injection(注入攻击)
→ SQL 注入:字符串插值拼接 SQL 语句 → XSS:.html_safe / dangerouslySetInnerHTML / innerHTML → 命令注入:shell=True + f-string / os.system() + 用户输入 → LDAP 注入、模板注入(SSTI)、路径遍历 → 检查方法:/[cs]so 的 checklist 与 /review 的 CRITICAL pass 共享
A04: Insecure Design(不安全的设计)
→ 缺失速率限制(用户可以暴力破解) → 缺失输入验证(信任前端传来的所有数据) → 安全决策依赖于客户端(前端隐藏的 isAdmin 字段) → 检查方法:读取架构文档和设计决策记录
A05: Security Misconfiguration(安全配置错误)
→ DEBUG = True 在生产环境 → 详细的错误信息暴露给客户端 → 默认密码未更改(admin/admin) → 不必要的 HTTP 方法开启(PUT/DELETE 未限制) → 过时的依赖(已知 CVE 漏洞)
A06-A10: 其余五大类
→ A06: 脆弱和过时的组件(npm audit / bundle audit) → A07: 认证和识别失败(弱密码策略、session 管理缺陷) → A08: 软件和数据完整性失败(不安全的反序列化、未签名的更新) → A09: 安全日志和监控失败(无审计日志、日志无完整性保护) → A10: SSRF(服务端请求伪造——LLM 生成 URL 的风险)
§4 STRIDE 威胁建模
六大威胁类别的代码级映射
Spoofing(欺诈——伪装成合法身份)
→ JWT 签名验证是否在任何地方都被强制执行? → session token 是否可预测? → API key 是否可以被伪造(简单 UUID 不够)? → 检查:认证中间件的所有绕过路径
Tampering(篡改——修改不应该修改的数据)
→ 数据库记录是否可以被越权修改? → 日志是否可以被外部修改? → Webhook payload 是否验签? → 检查:所有写操作是否有权限检查
🔍 实战案例——Tampering(篡改):
-- 危险:任何登录用户都能改任意订单 UPDATE orders SET status = 'cancelled' WHERE id = ? -- 安全:验证订单属于当前用户 UPDATE orders SET status = 'cancelled' WHERE id = ? AND user_id = ?
Repudiation(否认——做了但不承认)
→ 关键操作是否有审计日志? → 日志是否包含:谁、什么时候、做了什么、结果如何? → 日志是否防篡改(append-only)? → 检查:敏感操作(支付、删除、权限变更)的日志覆盖
Information Disclosure(信息泄露)
→ 错误消息是否暴露内部实现? → API 响应是否返回过多数据(用户密码 hash 在响应中)? → Git 仓库中是否有 .env 文件? → 检查:所有 error response 和 API 响应 schema
🔍 实战案例——Information Disclosure(信息泄露):
// 危险:API 返回了不该暴露的字段 app.get('/api/users/:id', (req, res) => { const user = db.users.findById(req.params.id) res.json(user) // 返回了 password_hash, ssn, email 等全部字段 }) // 安全:只返回必要字段 res.json({ id: user.id, name: user.name, avatar: user.avatar })
Denial of Service(拒绝服务)
→ 是否有无限制的循环/递归被用户输入触发? → 是否有未受保护的大查询(SELECT * 无 LIMIT)? → 文件上传是否有大小限制? → 检查:所有资源密集型操作的保护措施
Elevation of Privilege(权限提升)
→ 是否有"run as admin"的路径不验证当前用户? → 角色变更是否需要更高权限? → 检查:所有权限边界和角色变更路径
§5 审计输出——不只是"发现问题"
三层发现结构
CRITICAL(P0——立即修复)
→ 可远程利用的漏洞(无需认证) → 数据泄露风险(可读取任意用户数据) → 权限提升(普通用户变 admin) → 示例:SQL 注入在公开端点、未验证的 JWT、开放的 admin 端点
HIGH(P1——本周内修复)
→ 需要认证才能利用的漏洞 → 潜在的注入但输入源受限 → 信息泄露但影响范围有限 → 示例:已登录用户的 IDOR、XSS 在后台页面
MEDIUM(P2——sprint 内修复)
→ 配置问题(DEBUG mode、详细错误) → 弱加密但有其他保护层 → 日志不完整 → 示例:生产环境显示 stack trace、缺少速率限制
LOW(P3——改进建议)
→ 安全加固建议(不是漏洞,是改进) → 最佳实践偏离 → 示例:使用 bcrypt 而非 argon2、虽然有 HTTPS 但 HSTS 未配置
每条发现包含
→ 威胁类别(OWASP A01-A10 或 STRIDE S/T/R/I/D/E) → 文件位置 + 行号 → 攻击场景描述(攻击者如何利用) → CVSS 评分(如有充分信息) → 修复建议(具体代码示例) → 验证方法(如何确认修复有效)
§6 与其他系统的集成
/review 集成
→ /review 的 Security 专家调用 cso 的清单 → cso 是 Security 专家的"知识库" → Security 专家的输出补充 cso 的发现
/investigate 集成
→ cso 发现的安全漏洞 → /investigate 验证可复现性 → 确认后可利用性后升级严重度
/ship 集成
→ /ship 的审查就绪检查包括安全审查 → 发现 CRITICAL 安全漏洞 → 阻止 /ship
GBrain 集成
→ cso 的发现反馈给 GBrain 的 Security Smells 维度 → 持续追踪安全态势
结构拆解
Skill 结构模板:双模型安全审计
核心特征
- 管理对象: 代码库全量安全漏洞(非单次 PR 级)
- 核心原则: OWASP Top 10(攻击者视角)+ STRIDE(设计者视角)双模型互补,不依赖单一分析框架
- 关键设计:
- 三层发现结构(CRITICAL/HIGH/MEDIUM/LOW),每条发现包含攻击场景 + CVSS + 修复建议 + 验证方法
- 与 /review、/investigate、/ship 深度集成,CRITICAL 漏洞可阻止部署
- 审计报告包含 OWASP/STRIDE 覆盖度统计
通用结构
- 输入层: 代码库路径 + 审计范围(scope)+ 技术栈信息(framework, db)
- 分析层:
- OWASP Top 10 遍历(A01 访问控制 → A10 SSRF)
- STRIDE 六大威胁类别映射(Spoofing → Elevation of Privilege)
- 输出层: 分严重度的发现列表 → 审计报告摘要 → 修复优先级建议
- 集成层: 发现反馈给 /review Security 专家、/investigate 验证可复现性、/ship 审查就绪检查
§7 电商 Skill 案例:电商平台支付模块安全审计
🛒 实战案例:某电商平台即将接入第三方支付服务商(微信支付+支付宝),CTO要求在对接前对支付链路做一次全面安全审计。支付模块代码量约8000行(Node.js+TypeScript),涉及订单创建、支付回调处理、退款、对账四个核心流程。使用
/cso --scope payment启动OWASP Top 10 + STRIDE双重威胁建模审计。
- 审计范围确认:scope=pament模块,涵盖
src/payment/**/*、src/routes/webhook/*、src/services/*pay*。审计框架——OWASP Top 10:2021(9/10适用,A10 SSRF不涉及)+ STRIDE六维威胁建模(Spoofing/Tampering/Repudiation/Information Disclosure/Denial of Service/Elevation of Privilege全量覆盖)。- CRITICAL发现(3个):(1) 支付回调未验证签名——
src/routes/webhook.ts:45,支付宝异步通知notify_url接收后直接信任payload,攻击者可直接POST伪造支付成功消息将订单状态改为"已支付"→修复:调用支付宝SDKalipaySdk.checkNotifySign(params)验证签名;(2) 退款接口无鉴权——POST /api/payment/refund未验证请求者是否为订单所有者,攻击者猜测订单ID即可退款任意订单→修复:添加verifyOrderOwner中间件;(3) API密钥硬编码在Dockerfile——微信支付APIv3签名密钥通过环境变量直接写入Docker image→修复:使用CI secrets在运行时注入或使用KMS密钥管理服务。- HIGH发现(4个):(1)订单查询SQL注入——
db.query(SELECT * FROM orders WHERE id = ${orderId})使用字符串拼接→修复:参数化查询db.query('SELECT * FROM orders WHERE id = $1', [orderId]);(2)订单金额从req.body读取可被前端篡改→修复:金额从服务端数据库订单记录读取;(3)支付状态检查与扣款之间存在TOCTOU竞态→修复:使用数据库行锁SELECT ... FOR UPDATE;(4)退款审计日志不完整——缺少操作人IP和User-Agent记录→修复:补全审计日志字段。- MEDIUM发现(6个):错误消息泄露调用栈信息、支付接口无速率限制(可被用于暴力枚举订单号)、CORS配置
Access-Control-Allow-Origin: *过宽、日志中记录完整卡号(PCI DSS违规)、session超时24小时过长、bcrypt cost factor=10(建议≥12)。LOW发现3个:缺少CSP header、HSTS未配置max-age过短、密码强度未强制要求。- 审计报告与修复优先级:总分诊——CRITICAL 3个(必须修复后才能对接第三方,涉及资金安全和数据泄露)、HIGH 4个(必须在UAT前修复)、MEDIUM 6个(本sprint内修复)、LOW 3个(加入技术债务backlog)。修复后重新审计
/cso --scope payment --recheck——确认所有CRITICAL和HIGH已清除,MEDIUM剩余2个(日志PCI合规需要架构调整,列入下个sprint)。审计报告自动持久化到gstack-security-log并生成合规PDF归档。
🔑 启示:安全审计最危险的发现往往不是"代码写错了"——而是"代码实现了功能但遗漏了安全假设"。退款接口的功能代码逻辑正确(确实可以执行退款),但它假设"能访问这个API的人就是订单所有者"——这个假设在真实验证场景下不成立。/cso的价值在于系统性地验证这些安全假设,而非扫描代码语法错误。
[!info] 参考来源 OWASP Top 10 参考 OWASP Top 10:2021 官方文档。STRIDE 方法论参考 Microsoft Threat Modeling。电商支付安全参考 PCI DSS v4.0 支付卡行业数据安全标准。
§8 掌握检验
Q1:OWASP Top 10 和 STRIDE 两种安全方法论的核心视角区别是什么?
- A) OWASP 关注"攻击者怎么打进来"(基于真实攻击数据),STRIDE 关注"系统设计哪里脆弱"(基于威胁建模方法论)
- B) OWASP 只适用于 Web 应用,STRIDE 只适用于桌面应用
- C) OWASP 是微软的方法论,STRIDE 是 OWASP 社区的方法论
- D) OWASP 和 STRIDE 覆盖完全相同的威胁,只是名称不同
Q2:cso 审计中,以下哪个发现应被标记为 CRITICAL(P0)优先修复?
- A) 生产环境显示详细的错误堆栈跟踪
- B) 使用 bcrypt 而非 argon2 进行密码哈希
- C) 支付回调 webhook 未验证签名——攻击者可以直接 POST 虚假支付成功 payload
- D) 日志文件中缺少用户操作审计记录
Q3:电商支付链路中,"金额从前端传入"被标记为 HIGH 安全漏洞。请解释:为什么前端传入的金额不可信?攻击者如何利用这个漏洞(给出具体攻击步骤)?正确的架构设计应该从哪里获取金额——并说明这个"权威数据源"为什么比前端更可靠?
Q4:STRIDE 中的 Elevation of Privilege(权限提升)和 OWASP 中的 Broken Access Control(A01)在概念上有重叠但也有区别。请给出一个"同时属于两者"的例子,再给出一个"只属于 EoP 但不属于 A01"的例子,和一个"只属于 A01 但不属于 EoP"的例子。
Q5:cso 的每条安全发现都包含"攻击场景描述"和"CVSS 评分(如有充分信息)"。为什么攻击场景描述在安全审计中比 CVSS 数字更有工程价值?请从"开发人员如何理解并修复漏洞"的角度分析——一个只有 CVSS 7.5 但没有攻击场景描述的发现,对开发者的行动力有什么影响?
Q6:cso 审计发现"支付回调未验证签名(CRITICAL)"和"SQL 注入(HIGH)"——两者都被标记为严重,但 CRITICAL > HIGH。请问:在什么条件下,"未验证签名"可能实际上比"SQL 注入"的危害更低?这种"严重度可能随上下文变化"的现象,对安全审计的自动化评分有什么启示?
§9 答案
点击查看答案
Q1:A —— OWASP Top 10 是攻击者视角(基于真实世界的攻击数据统计,覆盖最常见的 10 种攻击向量),STRIDE 是设计者视角(基于微软威胁建模方法论,覆盖 6 种威胁类别:Spoofing/Tampering/Repudiation/Info Disclosure/DoS/Elevation of Privilege)。
Q2:C —— 支付回调未验证签名 = 可远程利用的漏洞(无需认证),攻击者直接 POST 虚假 payload → 订单状态变为"已支付"→ 直接资金损失。
Q3:攻击步骤:①浏览器开发者工具 → 找到下单请求 → 修改 req.body.amount 从 998 改为 0.01 → 发送;②服务端收到 amount=0.01 → 创建支付单 → 用户支付 0.01 元获得价值 998 元的商品。正确设计:服务端从数据库中查询订单记录获取金额——const order = await Order.findById(orderId); const amount = order.total_amount;。数据库中的订单金额是在"商品加入购物车时"由服务端计算的(商品价格 × 数量 × 折扣),这个计算链路的所有环节都在服务端——前端从未"决定"过价格,只是"展示"了价格。权威数据源 = 数据库,因为它是唯一不受客户端操控的持久化存储。
Q4:同时属于两者:普通用户直接访问 /admin/users 端点删除了其他用户——这既是访问控制的失败(A01:没有检查 admin 角色)也是权限提升(EoP:普通用户执行了 admin 操作)。只属于 EoP:一个 cron job 以 root 权限运行但只需要读取日志——如果这个 cron job 被攻击者利用,攻击者获得了不应该有的 root 权限(权限提升),但这不涉及"访问控制规则缺失"(cron job 本身就对系统有完全访问权——这是权限授予过多的问题而非规则缺失)。只属于 A01:用户 A 通过修改 URL 中的 user_id 参数查看了用户 B 的个人资料——这是水平越权(访问控制规则没有检查"资源归属"),但用户 A 并没有提升自己的权限级别(仍然是普通用户)。
Q5:CVSS 7.5 是一个数字——开发者看了之后知道"这是高危",但不知道从哪里开始修。攻击场景描述("攻击者可以用 Burp Suite 截获支付回调请求,修改 amount 字段后重新发送——因为 webhook 没有验签")让开发者:①理解了攻击路径(知道攻击者会通过什么入口进来);②知道了修复方向(添加签名验证);③能够验证修复是否有效(修复后用同样的攻击手法测试)。没有攻击场景 = 只知道"有问题"但不知道"什么样的问题"——开发者的行动力从"我知道怎么修"降级为"我需要先理解这是什么问题"——增加了一轮认知往返。
Q6:未验证签名危害更低的场景:如果回调 URL 是内网地址(只接收来自 API 网关的转发,API 网关已经验证了来源 IP 白名单),外部攻击者无法直接 POST 到 webhook 端点——此时实际可利用性降低。SQL 注入危害更高的场景:如果拼接的 SQL 涉及 DELETE 或 UPDATE 而不仅仅是 SELECT,攻击者可以修改数据库中的数据甚至删除整张表。启示:自动化安全评分(如 CVSS)需要上下文才能准确——同样的代码模式在不同架构中危害不同。cso 的设计通过"攻击场景描述"补充了纯数字评分的不足——但最终的严重度判断仍然需要人工理解和上下文分析。
(5/6 通过)
延伸阅读
- [[L6-30-版本发布报告|上一课:版本队列仪表盘]]
- [[L6-32-五层安全防护盾|下一课:五层安全防护盾]]
- [[L6-16-专家审查军团|相关:审查专家系统——Security 专家]]

评论区
共 0 条评论