首页 / 文章

打造以客户为先的开发者工具,无需盲目信任。

KitDev Space将哈希值、JWT及存档数据保存在浏览器中,仅在需要原生功能或跨主机操作时才会使用Bun,并会标注每个工具的执行位置。

发布者:REACTAPP.TOP阅读约 6 分钟1438 词

来源: How I built KitDev Space, an open source hub of developer tools that never has to ask you to trust it

将生产环境中的 JWT 粘贴到搜索引擎推荐的第一个解码器中,这是一种常见的习惯。虽然目的只是读取其中的声明信息,但该令牌仍然会离开设备。在转换工具中的 .env 文件处理以及 EXIF 数据提取工具中的照片处理中也会出现同样的情况:隐私政策声称服务器不会保存任何数据,而人们便盲目相信这一说法。

KitDev Space 的存在就是为了减少这种盲目信任。日常开发者工具不应要求用户信任任何操作者——包括创建该网站的开发人员。该产品的设计遵循了一条早期制定的规则,且这条规则被视作不可更改的准则。

规则

优先选择在客户端执行操作。只有当页面环境确实无法完成任务时,才需要调用后端功能。

前半部分并无争议。后半部分需要明确的定义,否则所有便捷方案都会转向服务器端处理。实际上符合条件的情况寥寥无几:

  1. 该操作需要原生库支持。编码AVIF或渲染SVG都需要真正的编解码器,而建立TLS连接则需使用套接字。
  2. 该操作必须与另一台主机通信。由于CORS限制,DNS查询、响应头信息、RDAP以及OpenGraph预览在页面端都会失败或本应失败。
  3. 该操作需要没有浏览器对应版本的运行时API,例如Bun.dns或Bun.Archive。
  4. 输入数据过大,无法在单个标签页中完整显示。

如果某个工具不符合以上任何条件,它就仍属于客户端处理。尽管存在服务器端实现需要20行代码、而浏览器端实现则需要200行的情况,但出于便捷性考虑并未设立例外规则,这些例外方案也从未被正式加入产品。

浏览器的功能超出预期

最初的估算认为需要大量的服务器端代码。但实际上,大多数开发者工具功能都可以通过平台API或无需离开页面即可运行的小型依赖项来实现。

  • 通过crypto.subtle.digest实现SHA-1至SHA-512的哈希计算功能
  • 通过crypto.getRandomValues获取随机数及标识符
  • 利用crypto.subtle实现AES-256-GCM、PBKDF2、HMAC等对称加密算法
  • 通过OffscreenCanvas结合createImageBitmap实现图像的尺寸调整、旋转和裁剪操作
  • 使用OffscreenCanvas.convertToBlob将图像导出为JPEG、PNG或WebP格式
  • 通过DataView逐字节读取文件以获取EXIF和GPS信息
  • 借助fflate库实现压缩及归档功能(gzip、deflate、tar格式)
  • 通过confbox处理YAML、TOML、JSONC、JSON5等配置文件格式
  • 使用以 WebAssembly 形式运行的 sql.js 实现内存中的 SQL 操作
  • JWT 面板利用 Web Crypto 检查 HS256 签名,完全无需通过 HTTP。AES 页面则在对应标签页内使用 PBKDF2 生成加密材料。归档浏览器可直接打开 tar 文件,无需上传。SQLite 工具则将数据库存储在内存中。其设计思路很常规:先全面了解平台功能,只有在缺少某些功能时才添加相应路径。

    Web Crypto 仍存在不足:不支持 MD5、CRC32 和 xxHash。虽然纯 JavaScript 的 MD5 库可以让哈希运算完全在本地完成,但该哈希工具还提供了 xxhash64 和 wyhash 等功能,将这些很少被使用的算法提供给每位访问者似乎并不合适。这些选项都需要通过服务器处理,选中时界面会用通俗的语言说明这一选择。明确指出哪种模式会在本地运行,总比假装什么都不会在本地处理要好。

    一个模块,两种路径

    为同一工具维护浏览器版和服务器版会导致隐性分歧。两个转换器会逐渐偏离,原本相同的输入在不同执行环境中会突然出现差异。早期的格式转换器就遭遇过这样的问题。

    理想的架构是一个共享模块,它既输出处理程序也输出一个小型功能探测器。用户界面通过该探测器发起请求,API路由则导入同一个模块,这样哈希逻辑就集中在一处。

    // shared/utils/crypto/hash.ts
    const SUBTLE_NAMES = {
     sha1: 'SHA-1',
     sha256: 'SHA-256',
     sha384: 'SHA-384',
     sha512: 'SHA-512'
    }
    
    export function canHashInBrowser(algorithm: HashAlgorithm): boolean {
     return algorithm in SUBTLE_NAMES
    }
    
    // simplified page logic
    const result = canHashInBrowser(algorithm)
     ? await hashInBrowser(input, algorithm)
     : await $fetch('/api/hash', { method: 'POST', body: { input, algorithm } })
    

    哈希处理、格式转换、代码格式化以及语义化版本控制都遵循这种架构。新的双路径工具会继承相同的结构,而非再创造另一种分离方式。

    服务器的实际用途

    基于后端的工具都运行在Bun上。它们的存在都是因为一个特殊的例外情况:

    • 证书检查需要打开真实套接字来读取证书链、扩展属性以及协商确定的加密算法。
  • 名称和邮件健康检查工具需要A/MX/TXT以及SPF、DKIM和DMARC配置。
  • 头部信息检测、OpenGraph预览功能以及RDAP都需要从第三方获取数据。
  • 当需要生成AVIF或ICO格式文件时,Image Studio和favicon打包功能会调用Bun.Image。
  • TS/JSX转译以及AST调试功能依赖于OXC的本地实现。
  • 服务器路由被视为负担,需遵循相同的预检清单。URL必须经过验证,且只能使用http或https协议。Localhost、私有地址范围、链路本地地址、云元数据端点,以及能够隐藏IPv4地址的IPv6过渡形式(如NAT64和Teredo,在构建拒绝列表时已被排除)均会被拒绝。目标端口有上限限制,以防止TLS检测扫描整个网络。系统会检查内容长度,以流式方式传输数据体,并在达到固定上限时停止读取而非持续缓冲。速率限制使用与x-forwarded-for无关的客户端密钥,而后者很容易被伪造。上传内容仅存储在内存中,不会保存到磁盘上。输入和输出数据也不会被保留。

    分析功能也遵循同样的规则。事件仅包含工具标识符,没有其他信息。可以查看cron可视化工具的使用情况,但无法看到所输入的表达式。

    使规则可见

    那条无人可见的规则属于营销用途,而非隐私控制机制。因此导航栏会标注操作的执行地点。

    每个条目都配有相应标识。标有“Client”的页面永远不会向服务器发送请求;而标有“Bun”的页面则意味着所有操作都会传送到后端。同时具备这两种路径的工具会省略标识,并注明哪种操作会导致标签页关闭。这些标记是由两个注册表标志生成的——正是这些标志决定了页面标题和搜索功能,因此说明文字与实际实现不会存在矛盾。

    该代码采用MIT许可协议,链接位于页脚。对于标有“Client”的页面,可通过打开对应模块并确认其从未调用任何路由来进行验证。设计的最后一点就是依靠验证而非信任。

    内容概览

    目录规模几乎每周都在变化,因此统计的人数到明天就会过时。使用频率最高的工具按功能分类如下:

    数据处理功能:可美化显示JSON,同时支持JSON5/JSONC格式;能从JSON中生成TypeScript类型定义;可在YAML、TOML、XML和CSV之间自由转换(还能将CSV数据行转换为SQL插入语句);可浏览大型CSV表格,并能在浏览器中运行SQLite编辑器。

    开发辅助工具:带有逐个标记说明的正则表达式编辑器;显示下次任务执行时间的cron日历;可将cURL转换为fetch、Axios、Python或Go语法的工具;用于将HTML/SVG转换为JSX或Vue格式的转换器;glob模式测试工具,以及本地tar文件浏览器。

    网络检测功能:证书链检查、DNS查询、邮箱认证状态监测、原始HTTP头部查看、CIDR地址计算、Cookie解码,以及RDAP查询功能。

    加密工具:哈希计算、HMAC算法、JWT格式检查、TOTP验证码生成、AES加密/解密功能,还有UUID和密码短语生成器。

    颜色工具:OKLCH格式转换、WCAG对比度评分、Tailwind配色渐变功能、CSS渐变组合,以及从图片中提取调色板。

    图像工具:合并裁剪/调整大小/旋转/转换功能、EXIF信息查看或删除功能、将SVG转换为1倍/2倍/4倍分辨率的PNG/WebP格式,以及能生成ZIP文件的图标包打包工具。

    没有账户系统与付费墙。主题会自动跟随操作系统设置,因此无需单独调整亮色/暗色模式。

    技术实现

    为保持简洁,其技术栈选择较为常规:浏览器端使用Nuxt 4与Nuxt UI 4,组合式函数来自VueUse,编辑器为CodeMirror,路由处理由Bun负责,测试则采用Vitest搭配Playwright,部署在Vercel平台上。

    需要您的帮助

    尝试使用 https://kitdev.space,有两份报告最为有用:一是显示缺少了哪些工具,二是判断是否有工具在本应仅处理本地数据的情况下向服务器发送了数据。出现第二种情况说明相关规则存在漏洞。

    仓库链接就在页脚,只需点击即可访问。欢迎针对新工具、修复问题或徽章错误提交议题和拉取请求。这样的平台越多人参与,就会越好——这也是该代码开源的主要原因。

    在其他地方开发类似工具时,只需保留那少数浏览器确实无法处理的场景列表即可。其余所有操作都应在用户本地机器上完成。