# MoonAnsi Guard 威胁模型

MoonAnsi Guard 处理的是已经产生的终端输出字符串。它不执行命令，不连接 PTY，不渲染终端界面，也不判断命令本身是否安全。

## 保护对象

- 日志平台中保存的构建输出；
- Web 页面中展示的命令输出；
- 聊天机器人或 AI Agent 返回给用户的工具调用结果；
- 自动化测试和远程执行平台中的 stdout／stderr；
- 需要归档、检索或二次分析的终端文本。

## 信任假设

调用方负责捕获输出、限制整体输入大小，并决定是否展示、保存或阻断内容。MoonAnsi Guard 负责识别字符串内部的终端控制序列，并返回安全文本和审计结果。

## 主要风险

| 风险 | 示例序列 | 严重级别 | 处理方式 |
|---|---|---|---|
| 剪贴板写入 | OSC 52 | dangerous | 删除并记录 |
| 私有终端负载 | DCS、APC、PM | dangerous | 删除并记录 |
| 截断或超长序列 | 未终止 OSC／CSI | dangerous | 截断并记录 |
| 隐藏超链接 | OSC 8 | warning | 默认删除并记录 |
| 标题伪装 | OSC 0／2 | warning | 删除并记录 |
| 光标移动 | CSI A／B／C／D 等 | warning | 删除并记录 |
| 清屏或擦除 | CSI J／K 等 | warning | 删除并记录 |
| 回车或退格改写 | CR、BS | warning | 删除并记录 |
| 普通颜色样式 | CSI m | info | 默认删除，可按策略保留 |
| 输入和显示模式修改 | CSI ? 2004／1000／1049 h | warning | 删除并记录 |
| 终端设备查询 | CSI n／c | warning | 删除并记录 |
| 工作目录或提示符伪造 | OSC 7／133 | warning | 删除并记录 |
| 桌面通知 | OSC 9／777 | warning | 删除并记录 |
| 文件或图片传输 | OSC 1337 | dangerous | 删除并记录 |
| 审计载荷二次泄露 | 完整序列写入报告 | dangerous | 使用脱敏报告 |

## 流式边界攻击

攻击者可能将一个控制序列拆分到多个输出块，使逐块字符串清洗器无法识别。例如 OSC 52 的引导符、载荷和终止符可以分别位于三个数据块。

`StreamScanner` 会保留尾部未完成序列，并在后续数据块到达后继续解析。调用方在逻辑流结束时必须调用 `finish()`，使残留序列被标记为截断风险。如果调用方对每个数据块单独调用 `scan`，则无法获得跨块状态保证。

## 审计数据最小化

结构化命中记录可能包含剪贴板、通知或文件传输负载。长期存储审计结果时建议使用 `ReportPolicy::redacted()` 或 `metadata_only()`。只有在隔离的调试环境中才建议使用 `full()`。

## 不处理的内容

- 不判断 Shell 命令是否恶意；
- 不阻止进程真实写入剪贴板，只处理已经捕获的输出字符串；
- 不做 HTML、Markdown 或 URL 安全过滤；
- 不解析图片、二进制文件或终端截图；
- 不模拟终端最终画面。

## 推荐接入策略

- 对来自外部命令、模型工具调用和用户上传日志的内容使用 `Policy::strict()`；
- 对可信内部构建日志可以使用 `Policy::styled()` 保留颜色；
- 对分块产生的进程输出使用 `StreamScanner`，不要逐块独立调用 `scan`；
- 生产环境使用 `ReportPolicy::redacted()` 或 `metadata_only()`；
- 当 `risk_level()` 为 `high` 时，建议阻断展示或进入人工复核；
- 当 `risk_level()` 为 `medium` 时，建议展示安全文本，并保留审计记录；
- 当 `risk_level()` 为 `low` 或 `clean` 时，可以直接展示清洗后的文本。
