---
title: "隐私与安全"
description: "ThinkTerm 会在什么时候通过网络发送什么、在磁盘上保存什么以及谁能读到、网页端、对程序打印出的链接和粘贴内容会先问什么、macOS 的权限提示，以及如何报告安全问题。"
url: "https://docs.closex.org/zh/thinkterm/privacy.html"
markdown_url: "https://docs.closex.org/zh/thinkterm/privacy.md"
site: "CloseX Docs"
product: "ThinkTerm"
language: "zh-Hans"
last_updated: "2026-11-08T12:04:16.000Z"
alternates:
  en: "https://docs.closex.org/thinkterm/privacy.md"
  zh-Hans: "https://docs.closex.org/zh/thinkterm/privacy.md"
  ja: "https://docs.closex.org/ja/thinkterm/privacy.md"
---

# 隐私与安全

> **文档编写中**
> 部分内容可能尚不完整。

ThinkTerm 不收集任何关于你、你的机器或你如何使用它的信息。没有遥测、没有统计分析、没有追踪器，项目方也没有接收这些数据的服务器。除了一次更新检查之外，ThinkTerm 通过网络发出的每一样东西，都是你自己发起的。

## 不经你操作就会发出的

只有更新检查。桌面应用运行期间，会向 GitHub 的 release API 询问是否有新版本：启动后大约十秒检查一次（前提是记录里的上一次检查已经早于检查频率），之后每过同样长的时间再检查一次。频率是 `设置 › 软件更新` 里的 `检查频率` —— `每 12 小时`、`每天` 或 `每周` —— 在你用这一行之前则是 `check_for_updates_interval_seconds`，默认十二小时。命令行工具、TUI 和会话 server 从不自行检查。`设置 › 软件更新` 里的 `检查更新` 在你按下时发出同样的请求。

这个请求是匿名的。除非你自己设置了 `THINKTERM_UPDATE_TOKEN`，否则它不带任何凭据 —— 那个变量只在访问私有 fork 时才有用。ThinkTerm 自己的代码从不读取 `GITHUB_TOKEN`，所以你为别的工具导出的 token，不会被一次你没有发起的检查发送出去。安装脚本会读取它，而更新会运行那个脚本，见下文。GitHub 看到这个请求，就像看到任何其他请求一样；制作 ThinkTerm 的人看不到。

`设置 › 软件更新` 里的 `自动检查更新` 开关可以关掉它；在你用过这个开关之前，在配置里写 `check_for_updates = false` 也能关闭。改动在一分钟内生效。这两项见 [配置](https://docs.closex.org/zh/thinkterm/configuration.md#更新检查)，更新流程的其余部分见 [更新](https://docs.closex.org/zh/thinkterm/updates.md)。

## 你使用某项功能时才会发出的

| 你做的事 | 发往哪里 |
|---|---|
| 通过 SSH、Mosh 或 ThinkTerm Connect 连接 | 你连接的那台主机 |
| 连接一台开着 `检测操作系统` 或 `识别远端程序` 的主机（新主机两项都是开的） | 那台主机，走同一条连接：检查它的发行版；或者把 ThinkTerm 的 shell 集成复制到那里的 `~/.config/thinkterm/`，并在登录 shell 的启动文件里加一行来加载它，此后这个 shell 每开始一条命令，都会把命令行报告给 ThinkTerm |
| 打开一篇显示网络图片的笔记 | 图片地址指向的那台服务器 |
| 在设置里按下 `检查更新`，或运行 `thinkterm update --check` | GitHub 的 release API，和后台检查是同一个匿名请求 |
| 连接一台没装 ThinkTerm 的 ThinkTerm Connect 主机，并同意安装 | 这台机器连 GitHub（只在你同意之后），查找发布版并取一份带签名的安装脚本，通过同一条 SSH 连接发给那台主机；然后那台主机以 SSH 用户的身份，从 GitHub 下载发布文件到 `~/.local` |
| 同意更新远端 server | 和安装一样，发生在你对那唯一一个问题回答 yes 之后，这个问题会说明那台主机上将有什么变化。在此之前什么都不会查。重启 server 是另一个问题 |
| 运行 `thinkterm update`，或按下 `安装更新` | GitHub：发布版 API，用来找到最新的发布版；安装脚本；以及发布归档 —— GitHub 会把归档下载重定向到它自己的存储，GitHub 慢时也可能由镜像提供（见下文） |
| 开启网页访问 | 打开你所生成链接的浏览器 |
| 打开内置 tailnet | Tailscale 的控制服务器，或你在 `Control server` 里设置的那台，用来加入并保持在 tailnet 里；到 tailnet 里机器的连接都经过它，也可能由 Tailscale 的中继服务器转发 |
| 为网页访问开启 `连接其他机器`，并在页面里打开一台机器 | 你指定的那台机器，由 server 通过 SSH 连接。如果那里需要安装或更新 ThinkTerm，server 会尽可能把自己的程序经这条连接复制过去，否则由那台主机从 GitHub 下载安装脚本和发布文件 |

`安装更新` 和 `thinkterm update` 会在你的环境里运行安装脚本。脚本在设置了 `GITHUB_TOKEN` 时会读取它并随请求发送，但只有在必须自己下载归档时才会这样；ThinkTerm 已经下载并核对过归档时，脚本不会再下载。只要 GitHub 记录了这个归档的校验和，ThinkTerm 就会这么做。

本页凡是说发布归档（在 Windows 上是安装程序）来自 GitHub 的地方，它也可能来自镜像：由别人运营、转发 GitHub 下载的主机。`下载来源` 为默认的 `自动` 时，以及在安装脚本里，只有 GitHub 慢或连不上时才会去试镜像。镜像能看到你的地址和你下载的是哪个版本，和 GitHub 一样。`安装更新` 和 `thinkterm update` 运行的查找发布版和安装脚本始终来自 GitHub；token 从不发给镜像，设置了 token 时根本不用镜像；而且只有 GitHub 记录了校验和、能核对镜像发来的内容时，才会用镜像。`设置 › 软件更新` 里的 `直连 GitHub`，或者脚本的 `--mirror direct`，会让所有下载都只走 GitHub。ThinkTerm 为远端 server 安装或更新时，会自己取得安装脚本和发布信息，再通过 SSH 发给那台主机。`下载来源` 为 `自动` 时，它们也可能来自镜像，但必须带有能用 ThinkTerm 内置密钥验证通过的签名；验证不通过的脚本会换成随 ThinkTerm 附带的那一份，未经验证的东西不会在那台主机上运行。主机自己下载发布归档，来源是 GitHub 或镜像，规则同上。有系统代理或环境里指定的代理时，更新请求会经过它。

笔记里的网络图片默认会加载，而加载一张图片会让那台服务器看到你的地址，和任何网页一样。`note_remote_images_enabled = false` 可以禁止它。

插件是你自己安装的程序，可以像其他任何程序一样使用网络。比如 ThinkTerm 源码里的 Stocks 插件，就会从 Yahoo Finance 获取报价。下载包里不含任何插件，见 [插件](https://docs.closex.org/zh/thinkterm/plugins.md)。

第一次打开应用时出现的设置页不会给这张清单增加任何内容。它会在这台电脑上查找 Herdr 会话、WezTerm 配置，以及你的代码编辑器、编程 agent 和 cmux 最近用过的文件夹，并且不会把其中任何东西发往别处。它只读这些程序已经写下的内容：Herdr 的会话文件，加上（Windows 除外）通过 Herdr 自己的本地 socket 询问哪些会话在运行；WezTerm 的配置文件；各编辑器的最近文件夹列表；以及 Claude Code、Codex、Pi 和 cmux 各自记下的所用文件夹。对 agent 的会话文件，它只取文件夹和日期，不取说过的话。它不会进入这些文件夹去看里面有什么，因为那可能让 macOS 在你还没选择导入之前就弹出访问文档或桌面的请求。

## 保存在本机的

ThinkTerm 把它的状态保存在你的用户账户里：Space、Project 和 Thread，SSH 主机簿，片段，最近使用的命令，各项设置。它们在各个系统上分别放在哪里，见 [配置](https://docs.closex.org/zh/thinkterm/configuration.md)。笔记 Vault 是你自己选的文件夹，里面是普通的 Markdown 文件。

终端输出保存在内存里，由应用或会话 server 持有。有一项设置会把其中一部分写到磁盘上，而且在桌面应用所在的机器上默认是开的：`设置 › 通用 › 重新打开时恢复窗格内容`。ThinkTerm 的终端按正常流程停下时 —— 连同终端一起退出应用、关机或注销、会话 server 停止 —— 每个本地 pane 的主屏幕和回滚历史（最多 10,000 行）会保存到终端状态目录的 `kept-output` 里，好在下次放回新 shell 的上方。布局一回来，记录就删除；如果那个 Thread 没再打开，15 天后也会删除；关掉这项设置会删除全部记录。写入之前，看起来像密码、token 或私钥的文字会换成 `•`，地址里带有这类内容的链接会被丢掉。这只是模式匹配，不可能认出所有秘密，所以请把 pane 里显示过的内容当作明文留在了磁盘上。在没有桌面应用的机器上，比如远程主机，要在那里运行 `thinkterm cli restore-output on` 才会保存任何东西；`restore-output off` 把它关上。见 [配置](https://docs.closex.org/zh/thinkterm/configuration.md#恢复窗格内容)。

`设置 › 工作区 › 系统通知` 默认开启。ThinkTerm 在后台时，一个 Thread 完成、开始等你、或因错误停下，它都会交给系统一条通知，内容是 Thread 的名字、这个状态，以及那里运行的程序自己说的话。此后系统会像对待其他应用的通知一样显示和保留它，可能包括锁屏。如果不希望 Thread 名字或程序上报的内容出现在那里，就关掉这个开关，或者取消你不想被通知的场合：开关下面的 `完成`、`等你` 和 `出错` 是分开选的。

在 macOS 和 Linux 上，最要紧的那些文件以只有你能读的 `0600` 权限写入：

- `secret.key`，加密已保存 SSH 密码的密钥
- 片段文件
- 你导出的备份里的文件
- 网页监听的 token 文件，以及它的证书和私钥
- `web_machines.json`，网页添加的机器以及为它们保存的密码
- `重新打开时恢复窗格内容` 保存的记录，放在只有你能打开的文件夹里
- `tailnet.json`，内置 tailnet 的设置，其中的认证密钥和节点密钥用同一个 `secret.key` 加密
- ThinkTerm 新建的笔记，除非所在文件夹给了它自己的权限

这挡得住这台机器上的其他账户，挡不住任何以你的身份运行的东西 —— 同步客户端、备份任务、插件 —— 它们读一个 `0600` 文件和 ThinkTerm 一样容易。这对保存的密码意味着什么，见 [远程](https://docs.closex.org/zh/thinkterm/remote.md)。

`thinkterm tailnet up --serve-ssh` 会让 tailnet 里的机器连到这台机器自己的 `sshd`，而 `sshd` 看到的来源是 `127.0.0.1` 或 `::1`，所以任何信任本地连接的规则也会作用于它们。除此之外没有别的东西会打开它；见 [远程](https://docs.closex.org/zh/thinkterm/remote.md#内置-tailnet)。

Windows 上没有对应的权限位可设，这些文件继承所在文件夹的权限；对默认的用户配置文件来说，就是你本人、SYSTEM 和 Administrators 组。为了让凭据不进入漫游配置文件（在某些域里，Windows 会在注销时把它复制到配置文件服务器），SSH 主机簿、它的密钥和 `web_machines.json` 放在 `%LOCALAPPDATA%\ThinkTerm\ssh\`，网页监听的证书放在 `%LOCALAPPDATA%\thinkterm\web-tls\`。

## 网页端

在你打开之前，网页访问是关闭的。打开之后，页面、脚本和字体都由你自己的机器提供；页面不会向任何第三方发出请求，也不会收集任何使用情况。

浏览器凭你生成的 token 进入，token 是链接的一部分。页面一加载就会把 token 从地址栏里拿走，放进这个标签页的 `sessionStorage`，标签页关闭时浏览器会将其丢弃。拿到这条链接的人，就在那台机器上拥有一个以你身份运行的 shell，所以它和 SSH 密钥一样是凭据。

只有配置了 `token_file`，服务端才会把 token 写入磁盘；否则它们只在内存里，重启后全部失效。对每个 token，它写下的是 token 的 SHA-256 摘要，而不是 token 本身 —— 所以文件被复制走也放不进任何人 —— 以及它的名称、创建时间、过期时间、最后使用时间，和对最后使用它的浏览器的粗略描述，比如 "iPhone · Safari"。不会记录任何设备的地址，服务端日志里记的是哪个 token 被放行，而不是谁用了它。

只有在监听绑定到非回环地址、而你又没有提供自己的证书时，才会生成自签名证书。证书里写着这台机器的主机名和它的地址，任何连到这个端口的人都能看到 —— 证书本来就是做这个的。

页面会把你对它的选择 —— 语言、主题、字号、配色方案、当时显示的 Space、面板宽度、命令面板最近的选择，以及它应当重新打开的其他机器（在 `thinkterm.machines` 下）—— 保存在浏览器的 `localStorage` 里，留在那台设备上。清除这个站点的数据就会忘掉它们。谁能访问这个端口、如何核对证书，见 [网页访问](https://docs.closex.org/zh/thinkterm/web.md)。

页面还可以通过 server 打开其他机器。这默认是关闭的：`设置 › 网页` 里的 `连接其他机器` 会对所有监听器开启，没有桌面的 server 则在 `web_servers` 的某个监听器上设置 `relay = true`。关闭它，已经打开的机器会在几秒内断开。开启后，发起连接的是 server，通过 SSH，用它自己的密钥、它的 SSH agent 里的密钥和它自己的 `~/.ssh/config`。桌面端主机簿里保存的主机也会列出来，保存了密码的主机会直接用那个密码登录，不再询问。所以页面能到达这台 server 的 SSH 配置所能到达的任何地方，还能自己添加任意主机和端口。token 本来就给了 server 上的一个 shell，从那里也能用同样的密钥，因此这并不增加额外的访问权限；但开启时链接一旦泄露，能到达的就不只是 server，还有那些机器。主机提出的问题 —— 密码、是否信任它的主机密钥、是否在那里安装 ThinkTerm —— 会在页面里问你，并经由 server 回答；你要求保存的密码或密钥口令，会加密保存在 server 上的 `web_machines.json` 里，和桌面端保存的密钥放在一起。在页面的新主机表单里填写的密码也以同样方式保存，你同意在某台主机上安装 ThinkTerm 的回答也会被记住。这个连接不是端到端的：SSH 会话终止于 server 而不是浏览器，所以浏览器和主机之间传递的内容都要经过它。其余见 [网页访问](https://docs.closex.org/zh/thinkterm/web.md#reaching-other-machines)。

## macOS 上的权限提示

macOS 会把一个程序做的事记在启动它的那个应用头上。ThinkTerm 启动你的 shell，你的 shell 启动你运行的一切，所以一条碰到受保护内容的命令 —— 比如 `find` 遍历到存放通讯录的文件夹，或者某个打开摄像头的工具 —— 弹出的提示上写的会是 ThinkTerm。提示的原文也是这么说的：*An application launched via ThinkTerm would like to access…*。ThinkTerm 本身没有任何去读取你的通讯录、摄像头、位置之类的代码。

放在后台会话 server 里的本地终端，是由那个 server 启动的，而不是由应用启动的，它会以自己的名义 `thinkterm-mux-server` 申请权限。一个你已经允许过 ThinkTerm 访问的文件夹，可能还需要为 server 再允许一次。ThinkTerm 如何告诉你被拒绝的是哪一个，见 [配置](https://docs.closex.org/zh/thinkterm/configuration.md)。

在 macOS 上，`设置 › 权限` 能在某个程序提出请求之前，就让你看到这些程序已经拥有什么：`完全磁盘访问`、`屏幕与系统录音`、`麦克风` 和 `摄像头`，各自显示为已允许、没有、被拒绝、还没问过或查不到，按你的终端归谁名下（应用还是会话 server）来读取。查看本身从不会让 macOS 弹出提示。要特别小心的是完全磁盘访问：一旦允许，终端里的任何程序都可以读写其他应用的数据，macOS 不会再问。见 [配置](https://docs.closex.org/zh/thinkterm/configuration.md#macos-上的权限)。

## 程序打印出的链接与粘贴内容 {#links-and-pastes-a-program-prints}

终端里的程序可以打印一个链接，让任何地址藏在任何文字后面；你粘贴的文本也可能带有换行，内容一到就把命令执行了。ThinkTerm 对这两种情况，都会先问再做。

点击链接时，网页，也就是 `http` 或 `https` 地址，会直接在浏览器里打开。其他任何地址 —— 文件、`mailto:`、`ssh://`、某个应用自己的 scheme，或者根本没有 scheme 的文字 —— 会先弹出一个小菜单，把地址显示出来，让你选 `用其他应用打开` 或 `取消`。地址里含有看不见的字符，比如零宽空格，或能让文字方向反转的控制字符，则根本不会打开：菜单会把这些字符按码点写出来，并显示 `没有打开：链接不安全`。ThinkTerm 交给系统打开工具的东西，不管是链接还是路径，只要以短横线开头就会被拒绝，因为 `open` 和 `xdg-open` 会把它当成选项；名字这样的文件可以写成 `./-name` 或完整路径。ThinkTerm 的日志只记录“打开过一个链接”，不记录它的地址。

`设置 › 终端 › 粘贴带换行的内容前先问` 默认是关的。打开后，带换行的粘贴会先问 `仍然粘贴` 还是 `取消`，但只针对没有要求括号粘贴（bracketed paste）的程序，也就是内容一到就逐行执行的那种。zsh 这类把整段当一次粘贴的 shell 不会被问，判断不出来的 pane 也不问。

## 插件

插件以你的身份、用你的权限运行。新插件在你允许之前保持关闭 —— 在设置或网页的设置里点 `允许`，或运行 `thinkterm plugin enable` —— 如果插件被移到别的目录，会再问一次。允许之后，ThinkTerm 也只在侧栏里显示它，但程序本身外面没有沙盒：它能读你的文件、使用网络、运行其他程序；在通过 SSH 访问的终端旁边，它还能请 ThinkTerm 在那台主机上做同样的事。安装插件时，像安装任何其他程序一样对待它。详见 [插件](https://docs.closex.org/zh/thinkterm/plugins.md)。

## 报告安全问题

请私下报告，使用 GitHub 的私密漏洞报告功能：打开仓库的 **Security** 标签页，选择 **Report a vulnerability**，或者直接前往 [github.com/RoversX/ThinkTerm/security/advisories/new](https://github.com/RoversX/ThinkTerm/security/advisories/new)。请不要为此开公开的 issue、discussion 或 pull request。

尽量附上以下内容：

- 版本号（`thinkterm -V` 的输出）和你的操作系统
- 涉及的部分 —— 桌面应用、会话 server、网页访问、SSH 或 Mosh 连接、插件 server
- 复现步骤，或者概念验证
- 攻击者能做到什么，以及事先需要具备什么

你应该会在一周内收到回复。复杂问题的修复可能需要更久，期间会告诉你进展。修复发布时，安全公告会随之公开并致谢你，除非你不希望署名；在那之前，请不要公开细节。

只支持最新的发布版，修复会进入下一个版本。报告前请确认问题在最新版上仍然存在。

### 什么算在范围内

仓库里的全部代码都在范围内，包括 ThinkTerm 从 WezTerm 继承的代码。如果某个问题也影响 WezTerm，请注明，以便同时向上游报告。

以下不算 ThinkTerm 的漏洞：

- 已安装的插件能做的事。它是你自己安装的程序，以你的身份运行。
- 已经持有有效浏览器 token、能读取你的 ThinkTerm 数据，或者能以你的身份登录的人所能获得的访问。token 和保护已保存密码的密钥都是凭据。
- ThinkTerm 只是负责运行的那些程序本身的问题，比如你的 shell、`ssh` 或 `mosh`。

## 其他来源的构建

以上所说，针对的是 ThinkTerm 的源码，以及它自己的发布流程在 GitHub 上发布的构建。从其他地方获得的构建，可能已被改成另一种行为。

## 相关

- [安装](https://docs.closex.org/zh/thinkterm/install.md) —— 安装脚本下载什么、校验什么
- [网页访问](https://docs.closex.org/zh/thinkterm/web.md) —— 开启网页访问，以及放行浏览器的那条链接
- [插件](https://docs.closex.org/zh/thinkterm/plugins.md) —— 已安装的插件能触及什么
- [远程](https://docs.closex.org/zh/thinkterm/remote.md) —— 保存的 SSH 密码及其保护方式
- [配置](https://docs.closex.org/zh/thinkterm/configuration.md) —— ThinkTerm 的文件放在哪里
