← 全部文章

为什么不要把敏感的 JSON 粘进在线工具

JWT、API 密钥、个人信息、数据库导出经常被粘到在线格式化器里。看清楚这些数据在服务端会经历什么 —— 以及为什么基于浏览器的工具更安全。

一个开发者撞到一个解析错误,把 API 响应里的 JSON 复制出来,粘到 Google 里搜出来的第一个在线格式化工具。那段 JSON 里包含用户 ID、邮箱地址、session token,或者一份内部配置文件。这每天在每个工程团队里都会发生几十次。本文讲清楚这到底会带来哪些风险 —— 以及为什么浏览器原生工具能消除这些风险。

在线 JSON 工具里最终会出现哪类数据

实际上,开发者粘进去的就是当下让他们头疼的东西。也就是说:

  • JWT token —— 里面有用户身份 claim、角色、过期时间。签名能防篡改,但 payload 是 Base64url 编码的明文:任何拿到你 token 日志的人都能读出里面每一个字段。
  • 含 PII 的 API 响应 —— 姓名、邮箱、电话、生日、地址。来自面向客户 API 的一页搜索结果可能包含几百条记录。
  • 配置文件 —— 数据库连接串、第三方 API key、feature flag 设置、内部服务 URL。
  • 数据库导出 —— 整张表的 JSON dump,有时为了调试而生成、直接粘进去。
  • 内部业务数据 —— 定价规则、合同条款、未发布的产品数据,没有公开分级但同样敏感。

这些在那一刻都不会让人觉得敏感。开发者想理解结构,而不是想分享数据。但把它粘到在线工具里这件事,跟把它发给一个第三方在技术上没有区别。

把数据提交给在线工具会发生什么

大多数在线 formatter、validator、diff 工具的工作方式是把你的输入发到一个服务端 endpoint、在那边处理、再把结果返回来。哪怕是声称「客户端」的工具,有时也会把数据发出去做日志、analytics 或错误追踪。数据沿这条路径会经历的事情如下。

服务端日志

很多框架默认会把请求 body 写进 web server 日志。一次 POST 你 JSON payload 的请求可能最终落在:

  • 存在磁盘上或一个日志服务里的应用日志(Datadog、Splunk、CloudWatch)
  • 错误追踪工具(Sentry、Bugsnag)—— 特别是当解析失败时
  • 「analytics」或「usage」表里的一行数据库记录
  • 工具运营方都不一定监控的 CDN 或负载均衡访问日志

日志保留策略千差万别。有的工具留 90 天,有的无限期保留。任何一种情况下,运营方 —— 以及任何获得他们系统权限的人 —— 都能读到你提交的内容。

第三方 analytics

很多在线工具会嵌入第三方 JavaScript 来做 analytics 或广告。这些脚本可以观察网络请求、表单提交和输入事件。如果工具把你的数据发到自己的服务器,analytics 层也能看到这次 HTTP 交互。

缓存和 CDN 存储

有些工具会按输入内容做缓存。两个用户提交了相同的 JSON,第二个就会拿到缓存的响应。输入可能在缓存里留几小时甚至几天。极端情况下,配置错误的缓存让用户的提交可以通过一个可预测的 URL 被公开访问。

搜索引擎索引

会生成可分享 permalink(含或引用你格式化后 JSON 的 URL)的 formatter,过去出现过被搜索引擎爬取的情况。在搜索引擎里搜内部配置文件里一段醒目的字符串,结果在一个 JSON formatter 域名下找到 —— 那场面相当难受。

合规风险

如果你的组织在 GDPR、HIPAA、CCPA 或类似框架下处理个人数据,把一个用户的数据粘到第三方在线工具里,可能就构成一次未授权的数据传输 —— 哪怕是无意的,哪怕工具看上去口碑很好。法规不会区分有意分享和工具选择不慎。它问的问题是:个人数据有没有离开授权处理范围?

对 HIPAA 覆盖实体来说,把受保护的健康信息发到一个没签 Business Associate Agreement(BAA)的第三方服务,无论数据有没有被滥用,都属于必须上报的违规事件。

浏览器原生工具的工作方式有何不同

现代浏览器有能力在 JavaScript 引擎里完整地跑复杂逻辑 —— 解析、校验、diff、格式化、编码 —— 完全不需要发网络请求。建立在这套模型上的工具,行为就像一个恰好通过 web 交付的本地应用。

当你把 JSON 粘到一个浏览器原生工具里:

  • 文本进入你浏览器内存里的一个 JavaScript 变量。
  • 一个 parser(也是 JavaScript)在同一个 tab 里处理它。
  • 输出被渲染进 DOM。
  • 没有任何 HTTP 请求把你的数据当 payload 发给任何服务器。

数据根本没离开过你的机器。它没法被日志、缓存或索引,因为它从未被传输过。

怎么验证一个工具是真的本地

「我们绝不存你的数据」这类说法很常见,又没法从外面验证。唯一靠谱的检查是你浏览器的 Network 面板:

  1. 打开 DevTools(F12 或 Cmd+Option+I)。
  2. 切到 Network 标签页,勾上 Preserve log
  3. 把 JSON 粘进工具,触发操作(格式化、校验等)。
  4. 按 XHR/Fetch 过滤请求。如果有任何出站请求带着你的输入做 payload,那这个工具就不是客户端的。

一个真正本地的工具不会出现任何带着你数据的出站 POST 或 fetch。你可能会看到静态资源(CSS、JS 文件)请求或 analytics ping,但里面都不会有你的 JSON payload。

// 一个本地工具会做什么 —— 没有网络调用:
const result = JSON.parse(userInput);   // 在浏览器里跑
render(result);                         // 更新 DOM

// 一个服务端工具会做什么:
const res = await fetch('/api/format', {
  method: 'POST',
  body: JSON.stringify({ input: userInput }),  // 你的数据离开了机器
});

实用模式:BAA、WebCrypto 与脱敏 helper

三种模式能堵掉大部分剩余风险:

  • 在涉及 HIPAA 的工作里准备 Business Associate Agreement(BAA) —— 如果你的团队处理受保护的健康信息,任何接触这类数据的第三方服务都需要事先签好 BAA。这就是为什么把 PHI 粘到一个随手找的 formatter(哪怕它「在本地跑」),既是技术问题,也是合规文档问题。
  • 客户端 WebCrypto —— 当你确实需要在浏览器里做哈希、签名、加解密或生成密钥时,标准的 crypto.subtle API 不用走服务器就能做。它是「解密这段 payload 让我看一眼」而又不把密文发出去的正确原语。
  • 脱敏 helper —— 调试时先把 JSON 跑过一个小的脱敏器,把已知敏感 key(password tokenemailssn)的值 mask 掉再粘到任何地方。一个二十行的函数远胜于在某个 analytics 工具的请求日志里发现 token。

团队层面值得制定的政策

个人意识能覆盖的范围有限。一份轻量级政策能补上:

  • 粘贴前先分级。 如果 JSON 含有姓名、邮箱、ID、token、密钥 —— 那就是敏感的。用本地工具或经审批的内部工具。
  • 维护一份已审批工具列表。 一份简短的、已验证为「本地优先」的工具清单,比一句宽泛的「请小心」好执行得多。
  • 永远不要在调试时分享生产凭证。 任何被粘进在线工具的 token 或 key,哪怕那个工具看起来安全,也要轮换掉。
  • 用脱敏样本调试。 粘贴前把真实用户值替换成合成数据。带 "email": "test@example.com" 的结构,对调试一个解析错误,跟真实邮箱一样有用。

常见问题

把敏感 JSON 粘到在线工具里安全吗?

只有当工具完全在你的浏览器里处理时才安全。服务端 formatter 可以把你的输入日志、缓存、索引下来 —— 而且把 PII 粘到第三方那一刻本身可能就违反 GDPR 或 HIPAA,无论你本意如何。

我怎么判断一个 JSON 工具是不是本地跑的?

打开 DevTools → Network,勾上「Preserve log」,跑一遍操作。如果没有任何出站请求带着你的输入做 payload,那它就是客户端的。请求静态资源和 analytics 请求没问题;带着你 JSON 的 POST 就有问题。

我已经把一个 token 粘到在线工具里了,该怎么办?

轮换它。任何接触过第三方工具的凭证或密钥都要当成已泄露处理,哪怕那个工具看起来很正经。别忘了 Base64 编码过的 token 仍然是明文

我们团队怎么从根本上避免这件事?

用浏览器原生工具,维护一份已审批工具列表,用脱敏样本数据("email": "test@example.com")调试,而不是真实记录。

fixjson.org 做了什么

fixjson.org 上的每一个工具 —— JSON 修复、JSON diff、YAML formatter、JSON Stringify、Base64 编/解码、URL 解码 —— 都完全在你的浏览器里跑。parser、diff 引擎、formatter 全是本地执行的 JavaScript。你可以在 Network 面板里验证:不会有任何带你输入的 POST 请求。

站点会从 CDN 加载一次静态资源(HTML、CSS、JS)。在那之后它能离线工作。没有任何输入被发到任何服务器。没有任何数据被日志、存储或分享。

  • JSON Fix —— 在客户端修复和格式化非法 JSON
  • JSON Diff —— 在客户端比较两份 JSON 或 YAML 文档
  • Base64 编码 & 解码 —— 检查 JWT payload 和 data URI 而不把它们发出去
  • URL Decode —— 在本地百分号解码 query string
  • Base64 不是加密 —— 为什么编码过的数据,任何拿到这串字符的人都能读