关于 reviewing-security-architecture
侧重安全性的软件架构审查技能,供审查者评估身份验证、授权、数据保护和信任边界,并核对设计是否符合 Bitwarden 架构决策。
主要功能
- 01审查令牌和会话管理
- 02检查各层的授权控制
- 03评估加密与数据分类
- 04识别并验证信任边界
- 05对照 Bitwarden ADR
适用场景
- 01审查身份验证设计
- 02发现跨服务的授权缺口
- 03评估敏感数据保护措施
- 04标记缺失或冲突的架构决策
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bitwarden/ ai-plugins --skill reviewing-security-architecture安装后在 Claude Code 中输入/reviewing-security-architecture确认已加载。
附带文件references/architectural-anti-patterns.mdreferences/crypto-algorithms.md
详细介绍
身份验证架构
令牌处理
审查基于令牌的身份验证的以下方面:
| 方面 | 安全模式 | 反模式 |
|---|---|---|
| 签发 | 短时效令牌,并提供刷新机制 | 永不过期的长期有效令牌 |
| 验证 | 每次请求都验证签名、签发者、受众和过期时间 | 仅验证签名,或跳过对“内部”调用的验证 |
| 存储(服务端) | 无状态 JWT 或服务端会话存储 | 将令牌存储在查询字符串或 URL 中 |
| 存储(客户端) | HttpOnly Secure Cookie 或安全的平台存储 | localStorage、sessionStorage,或未设置 HttpOnly/Secure 标志的 Cookie |
| 刷新 | 轮换刷新令牌(旧刷新令牌在使用后失效) | 可重复使用且不轮换的刷新令牌 |
| 撤销 | 令牌阻止列表,或短过期时间加刷新令牌轮换 | 没有针对已泄露令牌的撤销机制 |
会话管理
- 服务端会话应设置绝对超时时间(会话最长持续时间)和空闲超时时间
- 会话标识符必须通过密码学安全的随机方式生成,且长度足够(熵至少为 128 位)
- 身份验证状态发生变化(登录、权限提升)后,重新生成会话 ID
- 尽可能将会话绑定到客户端属性(IP 范围、用户代理),以检测异常
凭据存储
- 密码必须使用现代 KDF 进行哈希:Argon2id(首选)、bcrypt,或具有较高工作因子和唯一盐值的 PBKDF2
- 切勿单独使用原始密码学哈希函数来哈希密码(速度太快,且默认不使用盐值)
- 每个凭据都应使用唯一盐值,以防彩虹表加速暴力破解攻击
授权模式
基于角色的访问控制(RBAC)
// CORRECT — explicit role check at the API layer
[Authorize(Roles = "Admin")]
public async Task<IActionResult> DeleteUser(Guid userId)
// WRONG — checking role in business logic with string comparison
if (currentUser.Role == "admin") // Fragile, case-sensitive, easy to bypass
对象级授权
// WRONG — trusts the userId from the route, no ownership check
public async Task<Cipher> GetCipher(Guid cipherId) {
return await _cipherRepository.GetByIdAsync(cipherId);
}
// CORRECT — verify the requesting user owns the resource
public async Task<Cipher> GetCipher(Guid cipherId) {
var cipher = await _cipherRepository.GetByIdAsync(cipherId);
if (cipher.UserId != _currentContext.UserId)
throw new NotFoundException();
return cipher;
}
授权原则
- 每一层都要检查。 API 控制器、服务层和数据访问层都应执行授权检查。不要依赖单一检查点。
- 最小权限。 仅授予所需的最低权限。默认拒绝。
- 失败时关闭。 如果授权检查失败或抛出异常,则拒绝访问。绝不能在失败时放行。
- 不要信任客户端授权。 UI 可见性控制属于用户体验,而非安全措施。始终在服务端强制执行。
数据保护
静态加密
- 所有敏感数据都必须使用 AES-256 或同等算法进行静态加密
- 绝不能将密码学密钥直接存储在可被直接访问的数据库中,必须使用其他密钥对其进行封装
- 使用信封加密:使用数据加密密钥(DEK)加密数据,再将 DEK 使用密钥管理系统中的密钥加密密钥(KEK)加密
- Bitwarden 的端到端加密确保保管库数据在离开客户端之前已完成加密
传输加密
- 最低使用 TLS 1.2,首选 TLS 1.3
- 禁用较旧的协议(SSL 3.0、TLS 1.0、TLS 1.1)
- 使用强密码套件(密钥交换使用 ECDHE,加密使用 AES-GCM)
- 在适用的情况下,为移动应用使用证书固定
- 服务间内部通信也应使用 TLS
数据分类
审查架构时,请按分类识别数据:
| 分类 | 示例 | 所需保护措施 |
|---|---|---|
| 关键 | 加密密钥、主密码、保险库数据 | 端到端加密、HSM 密钥存储 |
| 机密 | PII、电子邮件地址、账单信息 | 静态加密和传输加密、访问日志 |
| 内部 | 组织设置、功能标记 | 传输加密、基于角色的访问控制 |
| 公开 | 营销内容、公开 API 文档 | 完整性保护 |
信任边界
当数据在信任级别不同的组件之间流动时,就存在信任边界。每次跨越边界都必须经过验证。
常见信任边界
Client ←→ API Gateway (user-controlled → server-controlled)
API Gateway ←→ Backend Service (internet-facing → internal)
Backend Service ←→ Database (application → data store)
Service ←→ External API (internal → third-party)
Browser ←→ Browser Extension (page context → extension context)
Main Thread ←→ Web Worker (different execution contexts)
信任边界验证
每次跨越边界时:
- 验证所有输入 — 检查类型、格式、范围和长度。不要信任上游验证。
- 验证调用方身份 — 处理请求前,先验证身份。
- 授权操作 — 验证调用方是否有权执行此特定操作。
- 清理输出 — 根据目标上下文对数据进行编码或转义。
- 记录边界跨越 — 与安全相关的边界跨越应可审计。
零信任原则
- 不要将内部网络位置视为身份验证的替代依据
- 服务间的每次调用都应经过身份验证和授权
- 假设网络已遭入侵 — 加密所有内部通信
- 对来自内部服务的数据进行与外部输入同样严格的验证
与架构决策保持一致
评估设计前,请检查 Bitwarden 的架构决策记录,了解是否已有与所审查组件相关的决策 — 参见 ${CLAUDE_PLUGIN_ROOT}/references/adr-alignment.md 中的基本规则(冲突 = 发现项、未记录的重要决策 = 差距、引用前先核实状态)。具体应用于架构审查时:
- 引用决策,而不只是指出问题。 当设计与已接受的 ADR 冲突时,请指出 ADR,并说明应更改实现,还是需要通过单独的 ADR 论证例外情况。
- 留意以下差距触发因素。 新的信任边界、新的身份验证模式、新的数据存储,或其他没有对应 ADR 的重大选择,正是应予以标记并记录,而不应直接实施的决策类型。
参考资料
如需详细的查阅表和代码示例,请参阅:
references/crypto-algorithms.md— 算法选择表(推荐与已弃用算法)以及常见的加密反模式代码示例references/architectural-anti-patterns.md— 常见的安全架构反模式(隐式信任、单点故障、不安全的默认设置、单体身份验证)及其修复方法
与威胁建模的关联
架构安全审查会直接为威胁建模流程提供依据:
- 信任边界识别 为数据流图中的边界划分提供依据
- 架构弱点 会成为威胁目录中的威胁
- 安全属性(身份验证、加密、访问控制)会映射到安全定义中的安全目标
- 发现的反模式 会成为 Bitwarden 参与模型第 1 阶段初始安全评估的候选项
进行架构审查时,请考虑这些发现是否需要邀请 AppSec 团队(#team-eng-appsec)参与完整的威胁建模会议。
评论
支持 Markdown