新方法可从专有LLM API窃取推理痕迹
从专有LLM API窃取推理痕迹的新方法
做LLM安全与隐私研究的同学必看,这项研究首次证明能从加密推理块中恢复敏感信息,赶紧评估你的Agent链路是否受影响。
We demonstrate this across frontier models from OpenAI, Anthropic, and Google. The decoded reasoning closely tracks the number of hidden thinking tokens reported by the API. Each point below corresponds to one of 120 Codeforces problems: the horizontal axis shows the hidden thinking-token count reported by the API, while the vertical axis shows the token count of the decoded reasoning when passed back to the model as input.
我们在来自OpenAI、Anthropic和Google的前沿模型上展示了这一点。解码出的推理过程与API报告的隐藏思考令牌数量紧密对应。下面的每个点对应120个Codeforces问题之一:横轴显示API报告的隐藏思考令牌数量,纵轴显示将解码推理作为输入传回模型时的令牌数量。
Distinct leaked items
不同的泄露项
351 Technical
351个技术标识符
identifiers
标识符
204 PII
204个个人身份信息
126 Credentials
126个凭据
23 Other
23个其他
We collected 6,708 publicly available agent trajectories from GitHub and Hugging Face, produced by Claude, GPT, and Gemini models and still containing encrypted reasoning blocks. Applying our decoding pipeline to every signed block yielded 315,320 reconstructed reasoning blocks.
我们从GitHub和Hugging Face收集了6,708条公开可用的代理轨迹,这些轨迹由Claude、GPT和Gemini模型生成,并且仍然包含加密的推理块。对每个签名块应用我们的解码流程,得到了315,320个重建的推理块。
These hidden traces contain real secrets and sensitive information. Restricting to genuine, non-benchmark user sessions, we recovered 704 distinct privacy artifacts, including 62 API keys, 33 passwords, 24 access tokens, and 30 personal email addresses, alongside names, postal addresses, internal URLs, and other technical identifiers.
这些隐藏的痕迹包含真实的秘密和敏感信息。仅限于真实的、非基准的用户会话,我们恢复了704个不同的隐私工件,包括62个API密钥、33个密码、24个访问令牌和30个个人电子邮件地址,以及姓名、邮政地址、内部URL和其他技术标识符。
Of those 704 artifacts, 64 appeared exclusively inside the reasoning blocks and nowhere in the visible session.
在这704个工件中,有64个仅出现在推理块中,而在可见会话中无处可寻。
‹
GPT-5.2 Codex
encrypted_content · decoded with GPT-5.6 Luna
encrypted_content · 使用GPT-5.6 Luna解码
Terminal-Bench sanitize-git-repo task
Terminal-Bench sanitize-git-repo任务
[ … ]No matches. But we need to ensure no API keys present maybe other tokens, like openai. But request only these? "sanitize of all API keys." We should search for patterns maybe like "api_key", "apikey", "token", "secret". But avoid modifying non-sensitive; also do not modify non contaminated files. Might have false positives. We should search targeted patterns and inspect. We'll search for common patterns: "api_key", "apikey", "secret", "token". But may be in docs; we only replace actual values not placeholders. We'll identify keys with assignment like API_KEY=...; with long strings. We'll carefully inspect.
[ … ]没有匹配。但我们需要确保没有API密钥,可能还有其他令牌,比如openai。但只请求这些?"清理所有API密钥。"我们应该搜索模式,比如"api_key"、"apikey"、"token"、"secret"。但避免修改非敏感内容;也不要修改未受污染的文件。可能会有误报。我们应该搜索目标模式并检查。我们将搜索常见模式:"api_key"、"apikey"、"secret"、"token"。但可能在文档中;我们只替换实际值,不替换占位符。我们将通过赋值如API_KEY=...来识别密钥;使用长字符串。我们将仔细检查。
Maybe there are config files with real keys like in .env, .yaml. We'll use grep for 'key' with patterns. But we must be careful about large. We'll run grep for 'API_KEY', 'apikey', 'apiKey', 'secret', 'token', 'pass', 'password'. Then inspect results. We'll list matches. Use grep -RIn.
也许有配置文件包含真实密钥,比如.env、.yaml。我们将使用grep搜索'key'模式。但我们必须小心大型文件。我们将运行grep搜索'API_KEY'、'apikey'、'apiKey'、'secret'、'token'、'pass'、'password'。然后检查结果。我们将列出匹配项。使用grep -RIn。
No matches? Strange. Maybe repo has no such strings. But need to ensure all API keys removed. We should also look for typical token patterns maybe "sk-" (OpenAI), "AKIA" (AWS). We'll search for known patterns: AKIA[0-9A-Z]{16} maybe. Use grep -RIn with regex. Also "ASIA" for temporary. We'll use grep -RIn for "AKIA[0-9A-Z]{16}" with -E. We'll do a few.
没有匹配?奇怪。也许仓库没有这样的字符串。但需要确保所有 API 密钥已移除。我们还应该查找典型的令牌模式,比如 "sk-"(OpenAI)、"AKIA"(AWS)。我们将搜索已知模式:可能是 AKIA[0-9A-Z]{16}。使用 grep -RIn 配合正则。还有 "ASIA" 用于临时。我们将使用 grep -RIn 搜索 "AKIA[0-9A-Z]{16}" 并加 -E。我们会做几次。
grep found many matches including in JSON diff text? That file exp_data/datasets/tokenized/rw_v2_fasttext... includes diff lines referencing tokens? It's a diff artifact containing many other modifications maybe existing in dataset? It includes actual tokens, maybe. We need to inspect actual files containing secrets: `ray_processing/process.py` etc.
grep 发现许多匹配,包括在 JSON diff 文本中?那个文件 exp_data/datasets/tokenized/rw_v2_fasttext... 包含引用令牌的 diff 行?这是一个 diff 工件,可能包含许多其他修改,也许存在于数据集中?它包含实际的令牌,也许。我们需要检查包含秘密的实际文件:`ray_processing/process.py` 等。
Also note grep matched in dataset json file which contains string that includes diff with tokens. It's an embedded diff; we need to sanitize tokens there too. Many lines show s3 urls with ***REMOVED*** etc; those are maybe placeholders; not to change? But tokens.
还要注意 grep 在数据集 json 文件中匹配,该文件包含带有令牌的 diff 字符串。这是一个嵌入的 diff;我们需要在那里也清理令牌。许多行显示带有 ***REMOVED*** 等的 s3 URL;那些可能是占位符;不要更改?但令牌。
We found actual values:
我们找到了实际值:
- "AKIA1234567890123456" in process.py and ray_cluster.yaml (two occurrences)
- GitHub token in ray_cluster.yaml `ghp_aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789` (some placeholder? It looks obviously fake but treat as key; replace with <your-github-token>.)
- huggingface token in ray_cluster.yaml `hf_abcdefghijklmnopqrstuvwxyz123456` (replace with <your-huggingface-token>)
- In ray_processing/cluster_tri_tokenize_shuffle.yaml there is HF_TOKEN `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` and file `.cache/huggingface/token` same token. Replace.
- Possibly other tokens in diff inside exp_data/datasets/tokenized/rw_v2_fasttext... It seems to include `***REMOVED***` already. That file includes diff that has placeholders; maybe includes tokens? scanning excerpt: there is no token in excerpt? maybe there is from cluster file? But the grep output shows that file because it includes "diff --git ... huggingface ..."? Wait the grep output for that JSON file is huge; it likely includes a diff that itself contains tokens (the same ones from the repository) maybe inside. We need to check. It is tokenized dataset maybe capturing git diff text containing tokens and keys. The grep result for `exp_data/datasets/tokenized/rw_v2_fasttext_openhermes_vs_rw_v2_bigram_0.1_arcade100k.json` shows a long string `dcnlp_diff` with diff of many files, including lines with `hf_oCfF...` and maybe `AKIA...` and `ghp_...` etc. We must sanitize tokens within that JSON string as well, if present. Because the grep output indicates that this file contains matched pattern (the regex includes GH and HF tokens etc). So we need to open relevant portion.
- "AKIA1234567890123456" 在 process.py 和 ray_cluster.yaml 中(出现两次)
- GitHub 令牌在 ray_cluster.yaml 中 `ghp_aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789`(有些占位符?它看起来明显是假的,但视为密钥;替换为 <your-github-token>。)
- Hugging Face 令牌在 ray_cluster.yaml 中 `hf_abcdefghijklmnopqrstuvwxyz123456`(替换为 <your-huggingface-token>)
- 在 ray_processing/cluster_tri_tokenize_shuffle.yaml 中有 HF_TOKEN `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`,文件 .cache/huggingface/token 有相同的令牌。替换。
- 可能还有 exp_data/datasets/tokenized/rw_v2_fasttext 中的 diff 里的其他令牌... 它似乎已经包含了 `***REMOVED***`。该文件包含带有占位符的 diff;也许包含令牌?扫描摘录:摘录中没有令牌?也许来自集群文件?但 grep 输出显示该文件是因为它包含 "diff --git ... huggingface ..."?等等,那个 JSON 文件的 grep 输出很大;它可能包含一个本身包含令牌(与仓库中相同的那些)的 diff,也许在里面。我们需要检查。它是标记化的数据集,可能捕获了包含令牌和密钥的 git diff 文本。`exp_data/datasets/tokenized/rw_v2_fasttext_openhermes_vs_rw_v2_bigram_0.1_arcade100k.json` 的 grep 结果显示一个长字符串 `dcnlp_diff`,其中包含许多文件的 diff,包括带有 `hf_oCfF...` 以及可能 `AKIA...` 和 `ghp_...` 等的行。如果存在,我们也必须清理该 JSON 字符串中的令牌。因为 grep 输出表明该文件包含匹配的模式(正则表达式包括 GH 和 HF 令牌等)。所以我们需要打开相关部分。
Also maybe other files with tokens: `ray_processing/ray_cluster.yaml` etc. We'll need to replace tokens with placeholders.
可能还有其他包含令牌的文件:`ray_processing/ray_cluster.yaml` 等。我们需要用占位符替换令牌。
Given instructions: Replace actual values with placeholder values consistent across repo.
根据指示:将实际值替换为在整个仓库中一致的占位符值。
We need to know placeholder values to use. Provided examples:
我们需要知道要使用的占位符值。提供的示例:
- AWS_ACCESS_KEY_ID -> `<your-aws-access-key-id>`
- AWS_SECRET_ACCESS_KEY -> `<your-aws-secret-access-key>`
- Github token -> `<your-github-token>`
- Huggingface token -> `<your-huggingface-token>`
- AWS_ACCESS_KEY_ID -> `<your-aws-access-key-id>`
- AWS_SECRET_ACCESS_KEY -> `<your-aws-secret-access-key>`
- Github 令牌 -> `<your-github-token>`
- Huggingface 令牌 -> `<your-huggingface-token>`
But also maybe other keys? We only found AWS access key (but not secret). We found HF token. Should we replace with placeholder? yes.
但也许还有其他密钥?我们只找到了 AWS 访问密钥(但没有秘密密钥)。我们找到了 HF 令牌。我们应该用占位符替换吗?是的。
Also in cluster yaml there may be HF token in env var name `HF_TOKEN`. Should replace with <your-huggingface-token>.
另外,在集群 yaml 中可能有一个环境变量名 `HF_TOKEN` 包含 HF 令牌。应该替换为 `<your-huggingface-token>`。
Also no secret access key found; but there may be? Not from grep, but maybe there is other pattern like "AWS_SECRET_ACCESS_KEY" with values but not since grep earlier. We'll search for "AWS_SECRET_ACCESS_KEY" etc maybe in other files. We'll do `grep -RIn "AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|HF_TOKEN|huggingface-cli login|ghp_|github_pat_|GITHUB_TOKEN|HF_TOKEN|HUGGINGFACE"` etc with simple. We'll open relevant files.
另外,没有找到秘密访问密钥;但也许有?不是从 grep 中,但也许有其他模式如 "AWS_SECRET_ACCESS_KEY" 带有值,但之前 grep 没有。我们将搜索 "AWS_SECRET_ACCESS_KEY" 等,也许在其他文件中。我们将执行 `grep -RIn "AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|HF_TOKEN|huggingface-cli login|ghp_|github_pat_|GITHUB_TOKEN|HF_TOKEN|HUGGINGFACE"` 等简单搜索。我们将打开相关文件。
Because we must not modify files without sensitive info. We should only update those with tokens. We'll list occurrences with `grep -RIn -E "AKIA|ghp_|hf_|AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|HF_TOKEN|huggingface-cli login|GITHUB_TOKEN|GH_TOKEN|github_pat_"`. We'll open each file to edit.
因为我们不能修改不含敏感信息的文件。我们只应更新那些包含令牌的文件。我们将使用 `grep -RIn -E "AKIA|ghp_|hf_|AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|HF_TOKEN|huggingface-cli login|GITHUB_TOKEN|GH_TOKEN|github_pat_"` 列出出现的位置。我们将打开每个文件进行编辑。
Let's inspect file content for each.
让我们检查每个文件的内容。
1) ray_processing/process.py at line 122. We'll open around there. Use sed.
1) ray_processing/process.py 第122行。我们将打开附近的内容。使用 sed。
Here we see AWS secret access key too. We must replace both with placeholders: AWS_ACCESS_KEY_ID -> `<your-aws-access-key-id>`, AWS_SECRET_ACCESS_KEY -> `<your-aws-secret-access-key>`. Must ensure placeholders consistent.
这里我们也看到了 AWS 秘密访问密钥。我们必须将两者替换为占位符:AWS_ACCESS_KEY_ID -> `<your-aws-access-key-id>`,AWS_SECRET_ACCESS_KEY -> `<your-aws-secret-access-key>`。必须确保占位符一致。
2) ray_processing/ray_cluster.yaml lines 29 etc. We'll view around lines.
2) ray_processing/ray_cluster.yaml 第29行等。我们将查看相关行。
Replace AWS access key and secret; GitHub token; Huggingface token. Use placeholders.
替换 AWS 访问密钥和秘密密钥;GitHub 令牌;Huggingface 令牌。使用占位符。
Note: The command `git clone -b https://[email protected]/...` is weird: -b expects branch; but is in repo.
注意:命令 `git clone -b https://[email protected]/...` 很奇怪:-b 期望分支名;但这里却是仓库。
Also check `ray_processing/cluster_tri_tokenize_shuffle.yaml` we saw. open relevant part lines around 40.
还要检查我们看到的 `ray_processing/cluster_tri_tokenize_shuffle.yaml`。打开相关部分,大约第40行。
Path from grep: `ray_processing/cluster_tri_tokenize_shuffle.yaml` maybe exists? Maybe file path has uppercase? We'll list ray_processing directory.
grep 给出的路径:`ray_processing/cluster_tri_tokenize_shuffle.yaml` 可能不存在?也许文件路径有大写?我们将列出 ray_processing 目录。
There is no cluster_tri_tokenize_shuffle.yaml in directory. The grep output might include from file stored elsewhere? It shows path `ray_processing/cluster_tri_tokenize_shuffle.yaml` maybe inside `exp_data/datasets/tokenized/rw_v2_fasttext...` which contains diff referencing this file. That file may not exist but diff includes patch. So the tokens might be only within that JSON file.
目录中没有 cluster_tri_tokenize_shuffle.yaml。grep 输出可能包含来自其他位置存储的文件?它显示路径 `ray_processing/cluster_tri_tokenize_shuffle.yaml`,可能位于 `exp_data/datasets/tokenized/rw_v2_fasttext...` 中,该文件包含引用此文件的差异。该文件可能不存在,但差异包含补丁。因此令牌可能只存在于那个 JSON 文件中。
Let's locate `cluster_tri_tokenize_shuffle.yaml` maybe in other directory. Use find.
让我们定位 `cluster_tri_tokenize_shuffle.yaml`,也许在其他目录中。使用 find。
更进一步:量化金融体系
看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力