以下内容由 Gemini 对代码进行了审计分析生成:


Dango 的安全与隐私模型分析

Dango 的安全与隐私模型建立在一个核心架构原则之上:它是一个纯粹的客户端应用程序。这意味着所有计算和数据存储都发生在用户的设备(浏览器)内部,不存在一个中心化的后端服务器来处理或存储用户数据。

基于此原则,我们可以从几个关键维度来分析其具体的实现方式及其安全含义。

1. 数据持久化:浏览器本地存储

  • 实现方式:应用利用浏览器的 localStorage API 来保存画布数据(节点、连线、视图状态)和用户偏好设置。所有数据都以 cc- 为前缀的键名存储在用户的浏览器中。
  • 安全含义localStorage 受浏览器同源策略的严格限制。这意味着只有 dango.ink 域本身可以访问其写入的数据,其他任何网站都无法读取或篡改。数据与用户的浏览器绑定,不会在不同设备间同步,也不会发送到任何远程服务器。数据清理也完全由用户控制,通过浏览器内置的“清除站点数据”功能即可彻底移除。

2. 数据交换:URL 片段标识符

  • 实现方式:当用户选择“分享”时,应用会将当前画布的完整数据通过 lz-string 库在客户端进行压缩,并将其编码后附加到 URL 的片段(Hash)部分,形式为 ...dango.ink/#<compressed_data>
  • 安全含义:根据 HTTP 协议规范,URL 中 # 之后的部分(即片段标识符)不会被浏览器发送到服务器。它完全是客户端侧的信标,用于页面内的导航或状态管理。因此,分享链接的生成、数据的压缩和解析全过程均在本地完成,数据内容仅在用户主动将链接发送给接收方时才会离开设备。这个过程不依赖任何中介服务器。

3. 外部通信:按需加载的字体资源

  • 实现方式:默认情况下,Dango 不会发起任何网络请求。唯一的例外是当用户手动启用“手写风格”选项时,它会向 fonts.googleapis.com 请求加载一个手写字体文件。
  • 安全含义:这是一个显式、可选且单一目的的网络请求。它不携带任何用户身份或画布数据。如果用户对与 Google 服务器的任何通信感到顾虑,只需不启用该选项,即可确保应用在完全离线的环境中运行。

4. 部署与运行环境:纯静态文件服务

  • 实现方式:Dango 的线上部署模型极为简单。它通过 Nginx 将一个预先构建好的、内联了所有 CSS 和 JavaScript 的 index.html 文件作为静态资源提供给浏览器。
  • 安全含义:服务端不涉及任何动态语言运行时(如 Node.js, PHP, Python),也没有数据库。这使得传统的服务器端攻击向量(如 SQL 注入、远程代码执行)几乎不存在。攻击面被最小化到仅限于静态文件托管服务本身。

5. 浏览器扩展:最小权限原则

  • 实现方式:为 Firefox 提供的配套扩展在 manifest.json 文件中申请了最低限度的权限。
    • "permissions": ["tabs"]:仅用于在用户点击扩展图标时,能够找到或创建一个 Dango 的标签页。
    • "data_collection_permissions": {"required": ["none"]}:这是向 Firefox 商店和用户明确声明,该扩展不收集任何形式的数据。
  • 安全含义:扩展的功能被严格限制在窗口管理上,它不读取页面内容,不监控网络请求,也不向任何地方发送数据。Firefox 的审查机制也为这一声明提供了额外的保障。

6. 供应链风险:极简的第三方依赖

  • 实现方式:应用在运行时仅依赖一个外部库 lz-string.min.js,用于数据压缩。它没有引入任何大型前端框架(如 React, Vue),核心逻辑均由原生 JavaScript 实现。
  • 安全含义:依赖项越少,潜在的供应链攻击风险就越低。lz-string 是一个功能单一、代码量小且久经考验的库,其行为可预测且易于审计。这与依赖数百个包的大型项目形成了鲜明对比。

总结

我们可以将 Dango 的安全模型归纳如下:

维度 实现方式 安全性保障
数据存储 纯客户端,无后端数据库 数据从不离开用户设备,杜绝了服务端数据泄露的可能
数据分享 客户端 URL Hash 生成 分享内容不经过服务器,由用户点对点传输
网络通信 默认无,可选的字体加载 最小化与外部服务的交互,且过程透明、可控
运行环境 纯静态 Nginx 服务 无服务器端动态逻辑,攻击面极小
依赖管理 零运行时框架,单一功能库 供应链风险被控制在最低水平

总的来说,Dango 的设计选择体现了一种纵深防御思想,但防御的重心完全放在了客户端。通过从架构层面根除对服务器的依赖,它系统性地消除了与数据隐私和服务器安全相关的一整类风险。用户对自己的数据拥有绝对的控制权。