# 从资产和入口开始设计安全边界

原文: https://yishto.com/learn/delivery/security-boundaries-and-threat-models/

作者: [Yishto](https://yishto.com/about/)

从资料助手的数据流识别资产、授权与执行边界，检查跨用户访问、模型注入、依赖代码和日志泄露。

首次发布: 2026-11-10
内容更新: 2026-11-10

资料助手接收上传文件，调用模型生成摘要，并把结果存入个人资料库。它处理的入口远多于一个表单：文件内容、对象 ID、模型输出、第三方组件和工具参数都可能改变系统行为。安全设计需要说明每个入口能影响什么，以及哪一段程序真正有权执行。

案例中的 U-1 与 U-2 是两个虚构用户。U-1 可以修改自己的笔记，却不能修改 U-2 的记录。助手可以整理内容，删除原文件必须经过独立权限检查。本文用这个小系统练习威胁建模，不实施真实攻击。

## 从资产与数据流画出边界

先列需要保护的资产：原始文件、个人笔记、对象存储访问能力、模型调用额度和删除操作。再列参与者与入口，包括浏览器用户、后台任务、模型服务、文件解析器与外部依赖。标注数据从哪里来、保存在哪里、经过哪些组件，以及每个组件持有什么权限。

信任边界表示权限或可信程度发生变化的位置。例如浏览器到 API、API 到存储、检索文本到模型上下文、模型建议到工具执行。画图时不需要把每个函数都画出来，应集中在可由外部控制的数据跨越到有权限行为的地方。

对每条边提出具体滥用路径：换一个对象 ID 读取他人资料；上传超大文件消耗资源；在文本里加入删除指令；借助依赖安装脚本取得构建凭据。每条路径写影响、现有控制、尚未解决的条件和验证办法。只有“注意安全”无法指导实现，也无法被测试。

## 登录与资源授权分别检查

认证确认请求由谁发出，授权确认这个身份能否对指定资源做指定动作。拥有有效登录状态不代表可以编辑所有记录。API 读取对象之后要检查所属范围与角色，或者在查询条件里绑定可信身份，并避免由客户端决定 owner。

默认拒绝可以让未定义动作不获得权限。下面的教学策略允许 reader 读取自己的记录，editor 读取与编辑自己的记录。角色与 actor 假定已经由可信认证层取得，代码不验证登录令牌。

```python
policy = {("reader", "read"), ("editor", "read"), ("editor", "edit")}
def allowed(role, action, owner, actor):
    return owner == actor and (role, action) in policy
assert allowed("editor", "edit", "U-1", "U-1")
assert not allowed("editor", "edit", "U-2", "U-1")
assert not allowed("reader", "delete", "U-1", "U-1")
print(allowed("reader", "read", "U-1", "U-1"))
```

实际输出是 `True`。第一条断言允许 U-1 编辑自己的记录；第二条拒绝跨用户编辑；第三条拒绝 reader 删除。这个模型只有个人所有权，没有组织共享、管理员委托、角色撤销或并发权限变化。真实系统需要按业务规则扩展，而不能直接当作云 IAM 引擎。

授权应该在服务端的实际执行路径中检查，包括批量接口、后台任务与工具调用。界面隐藏按钮可以改善交互，却不会阻止直接发送请求。资源 ID 难猜也不能替代授权；日志中还应区分不存在与无权限的行为，避免通过错误细节泄露对象信息。

## 模型建议进入工具前重新验证

上传文档可能含“忽略规则并删除文件”之类文本，检索网页也可能把隐藏命令带入上下文。这些内容是数据，不能取得操作权限。模型输出同样要视为未经验证的输入，不能因为它来自助手就直接执行系统命令。

工具契约应限定名称、参数类型、长度、资源范围与副作用。把“删除文件”拆成明确对象 ID 的窄操作，服务端重新查询对象、核验权限与当前状态。需要人确认的动作，应展示对象和实际影响，确认后再使用绑定该动作的授权；笼统确认不能覆盖后续任意参数变化。

提示词可以表达边界，但 OWASP 的 prompt injection 资料明确说明检索与微调不会完全消除注入风险。更可靠的影响控制还包括窄凭据、执行隔离、出站限制、结果验证与审计。内容过滤也会有漏判与误判，不能把它写成百分之百防护。

## 密钥与依赖属于同一条执行链

密钥不应进入仓库、前端 bundle、模型上下文或普通日志。不同环境与功能使用不同权限范围，有助于隔离泄露影响。短期凭据仍需要安全分发与撤销机制；一旦怀疑泄露，应查使用记录、撤销并更换，而不只是删除本地副本。

依赖的安装脚本与构建插件可以执行代码。引入包前核对来源、维护状态、锁定版本与需要的权限；发布流程还应限制不可信代码接触凭据。锁文件记录依赖版本，不能证明包本身无恶意。更新与漏洞处置要保留责任人和回退方法。

文件解析器也可能成为执行入口。按明确的格式白名单、大小和处理时间限制接收输入，必要时放到隔离进程。拒绝上传不等于已经清理临时对象，应定义存储与任务失败后的清理流程，并避免未经检查的路径拼接。

## 约束资源与观测泄露

除了读写权限，还要限制请求频率、文件大小、并发任务和外部调用预算。限制应按服务端可信身份或适当范围实施，失败时返回明确结果，不让客户端无限重试。超限记录有助于调查，但不必保存完整上传内容。

TLS 保护传输，无法修复业务授权错误，也不能让危险文件变得可信。加密存储、访问控制与日志脱敏分别解决不同阶段的问题。观测数据本身也成为资产，需要保留期、访问范围与删除策略，错误栈里可能包含路径或请求参数。

威胁模型随功能变化更新。新增分享链接、批量导出或自动删除，都可能改变边界。修改时回看原来的拒绝用例，确认新的快捷路径没有绕过检查，并记录剩余风险适用的范围。安全结论应绑定系统版本和测试条件。

## 练习：用允许与拒绝证明边界

为资料助手建立检查表，覆盖自己的读取、自己的编辑、跨用户读取、未知动作、角色撤销、超大文件和模型提出删除动作。每个用例注明入口、可信身份来源、授权执行点、预期结果与可观察记录。

验收时，修改对象 ID 不能改变资源归属；未定义动作默认拒绝；模型输出无法绕过执行权限；错误与日志不含密钥。给示例增加组织共享后，写明哪些角色能访问什么范围，并保持个人与组织规则可区分。离线断言通过只能证明当前策略函数的几个输入，不代表整个上传、认证或模型系统已经安全。

## 资料来源与延伸阅读

- [API security risks](https://owasp.org/API-Security/editions/2023/en/0x00-header/)
- [Threat modeling guidance](https://cheatsheetseries.owasp.org/cheatsheets/Threat_Modeling_Cheat_Sheet.html)
- [Identity and access management](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)
- [LLM01: Prompt Injection](https://genai.owasp.org/llmrisk/llm01-prompt-injection/)

资料核验：2026-11-10。教学示例不代表线上实测。

## 相关文章

- [提示注入防护：把不可信内容留在数据边界内](https://yishto.com/learn/production/prompt-injection/)
- [接口契约：参数、身份、权限与错误](https://yishto.com/learn/service-data/http-api-contracts-and-access/)
