# 星连开源 App 安全评测：凭据存储、连接退出与发布签名

VPNDevelop结合固定版本源码与测试记录，分析第一代开源 App 的2项中危、1项低危问题：完整凭据明文存储、退出后的过期连接续行，以及Android发布签名配置。前两项由合成本地测试复现，签名项仅经静态核对；该版本的Flutter测试未全部通过。以下从开发与交付角度说明问题影响和修复验收方法，结论仅适用于受审版本。

报告日期：2026-11-13；整理日期：2026-11-13T20:17:00+08:00。

受审提交：0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68

仓库：https://github.com/SingLinkLabs/singlink-vpn-app

本文为VPNDevelop对该开源项目的审查与分析，结合公开源码、审查记录和测试证据，从产品开发与工程实践角度评估功能实现、安全边界及改进方向。结论以注明的源码版本和测试范围为准；源码审查不等同于对当前商业客户端或线上服务的安全认证。

## 测试范围

- 凭据持久化与退出时序（已执行）：报告A-REPRO-R2：2项合成复现观察到缺陷；没有窃取真实账号或修改真实系统代理。
- Flutter静态分析（已执行）：报告A-ANALYZE-CLEAN：Flutter 3.35.6 / Dart 3.9.2，无分析器问题，退出码0。
- Flutter完整测试（已执行）：报告A-FLUTTER-CLEAN：77项可见成功、6项截图比对失败、2项跳过及1项清理错误，整套退出码1。
- Go隧道基线（已执行）：报告A-GO-BASELINE：3个顶层测试通过，使用内存模拟包与本机节点；tunnel包181/213语句覆盖，非整个App覆盖率。
- Windows真实核心C ABI（已执行）：报告A-CABI-SMOKE：本地解析、启动、HTTP 204探测、停止及1000次状态/复制/释放循环；不是公网测速或内存安全证明。
- Android正式签名（静态检查）：已核对固定版本Gradle配置和CI流程；报告未构建APK、检查产物证书或验证当前商用客户端。
- 已知依赖漏洞（已执行）：报告Windows/Linux源码视角govulncheck未报告匹配，24个Pub锁定包的OSV查询无匹配；仅限当时公告库与所查版本。
- Go并发竞态检测（受阻）：报告A-GO-RACE-R3：ThreadSanitizer影子内存分配错误87，未得到有效竞态检测结果。
- 原生设备与系统代理（未覆盖）：无Android模拟器、iOS真机、macOS主机或完整Windows GUI发布版测试；原始真节点与真实注册表测试跳过。
- 生产运营与网络可用性（未覆盖）：未审商用客户端二进制、生产节点、支付、账号系统、无日志政策，也未测大陆连通性、流媒体或长期负载。

## 问题清单

### A-01 完整连接凭据以明文保存在应用状态中

中危；状态：受审版本未修复，尚无修复后复测。

证据：报告A-REPRO-R2调用真实存储逻辑，用刻意无效的合成凭据标记验证JSON可读回完整链接；固定源码的Profile序列化与AppStore保存逻辑支持这一结论。

影响：前提是对方已经能读取状态文件或副本。完整有效链接可能包含令牌与设备私密材料，带来冒用风险；未证明绕过系统文件权限、移动端沙盒或完成备份窃取。

建议：将节点名称等普通资料与凭据分开；使用操作系统支持的秘密存储、备份排除和旧文件迁移。分别验证四个平台的锁屏、备份、转移、重装和凭据撤销行为。

### A-02 关闭后的旧连接操作仍可恢复状态

低危；状态：受审版本未修复，尚无修复后复测。

证据：报告A-REPRO-R2使用延迟的假核心与假代理执行器，证明关闭完成后，较早启动操作的异步续行仍可把控制器标记为已连接。

影响：属于本地生命周期时序问题，可能导致状态或代理清理不一致。报告未实际改写OS代理，也未证明真实退出后出现流量泄漏；与协议P-04是不同层的相关问题。

建议：关闭前使未完成连接失效；在异步返回后核对操作代次和关闭状态，保证重复清理安全。协调修复P-04，补测启动中退出、权限拒绝、换网和真实窗口关闭。

### A-03 Android发布构建沿用调试签名配置

中危；状态：受审版本未修复，尚无修复后复测。

证据：固定版本android/app/build.gradle.kts的release构建类型明确选择debug签名；这是静态配置证据，不是APK证书实测。

影响：未经修改的发布流程缺少受管理的正式签名身份，属于上线前发布控制缺口。未证明攻击者持有私钥、公开APK遭伪造，或不同证书的更新会被Android接受。

建议：配置受保护的正式签名，缺少正式配置时阻止发布构建；独立核对产物证书、哈希与来源版本，验证升级连续性和密钥轮换。调试产物与正式版本分开标识。


## 这份评测能回答什么？

它回答的是：指定第一代开源客户端如何保存凭据、控制连接状态、调用原生核心，以及哪些发布与平台验证仍未完成。它不回答“现在的星连商用客户端是否完全安全”，也不提供VPN推荐分数。

VPNDevelop从客户端开发、凭据保护和版本交付的角度，对这个开源项目进行审查与分析。本文结合固定版本源码与2026年11月13日v1.0审查记录，说明问题的触发条件、实际影响和改进建议。测试结果引用该版本已有的本地验证记录，修复后的复测状态另行列明。

## 版本与依赖必须一起固定

适用App版本为 **0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68**。报告同时固定协议依赖为 **6540bf335d0b370453421dabebafc2d1fc8840ea**，不能换成未来的主分支后继续沿用本页结论。

报告记录188个受版本控制文件，包含素材和平台模板。盘点这些文件不等于逐行审核所有依赖、生成文件或操作系统组件。重点审查范围是凭据序列化、核心接口、平台代理、移动隧道和构建配置。

已有测试记录以Windows x64为执行环境，正式Flutter基线为3.35.6 / Dart 3.9.2。测试未覆盖Android模拟器、iOS真机或macOS主机，也未完成Windows整套GUI发布构建；不能将这些本地结果外推到所有平台。

## 客户端架构与保护边界

| 层次 | 主要职责 | 必须区分的边界 |
| --- | --- | --- |
| Flutter界面与状态 | 导入节点、保存资料、连接/关闭、显示状态 | 界面显示“已保护”不等于所有应用流量已受保护 |
| Dart FFI与Go核心 | 解析、启动、停止、状态查询及内存交接 | 正确加载核心和释放返回数据，需要专门测试 |
| Windows / macOS | 配置系统代理并尝试恢复旧配置 | 系统代理不是全设备封包隧道；忽略代理的软件可能直连 |
| Android / iOS | VpnService / NetworkExtension与TUN桥接 | 源码中存在路由与DNS配置，不等于真实设备防泄漏已验证 |
| 构建与发布 | 依赖选择、核心封装、产物签名 | 原型能构建不等于具备可追溯的正式发布身份 |

桌面系统代理只覆盖遵循相关代理设置的程序。原始UDP、自带直连逻辑的软件及被绕过的本地地址，不能因为一个连接图标就视为已入隧道。固定版本README也明确区分桌面代理与移动端VPN实现。

## 如何解读测试结果，而不是只看“通过”

Flutter整套测试退出码为 **1**：77项可见成功之外，还有6项golden截图比对失败、2项跳过和1项清理错误。因此不能写成“全部测试通过”。报告将截图差异关联到跨平台字体和偏向macOS的参考图；这些失败本身不是加密或网络故障的证据，也不应重生成参考图来隐藏差异。

清理错误发生在Windows测试仍加载模拟DLL时删除临时目录。原始真节点测试和真实注册表测试因执行条件未满足而跳过。合成本机C ABI检查是另一组测试，不会补齐这两个缺口。

Go的 **84.98%** 是tunnel包181/213条语句的覆盖率，不是整个App的安全覆盖率。记录中的 **12 ms** 是本机HTTP 204功能探测时间，不是VPN延迟排名；**1000次**复制/释放循环也不是内存泄漏已排除的证明。

两项缺陷复现测试通过，表示测试成功观察到了不安全行为，而不是缺陷被修复。并发检测在有效运行前受ThreadSanitizer错误87阻断，不能据此宣布没有竞态。

## 隐私与DNS：源码检查不等于运营认证

报告未在所查第一方路径识别到独立分析SDK或例行流量载荷日志，但这不能证明生产节点不记录数据。设备上完整凭据的存储、客户端诊断记录和服务端运营日志是三个不同问题。

报告描述的DNS桥将拦截到的UDP 53查询经节点转换为TCP DNS。它不是“出口到上游也使用DoH或DoT”的承诺。客户端连通性探测、出口IP查询、节点域名解析和应用自己的DNS流量，也需要分别分析。

没有原生设备抓包、断网/换网和进程终止测试，就不能给出DNS、IPv6、WebRTC、持续断线保护或系统锁定模式的认证结论。本页同样不包含大陆网络可用性测试。

## 修复与复测应该如何安排？

1. **先保护凭据。** 使用系统秘密存储，处理旧明文副本和备份；四个平台分别以合成凭据验证，不拿真实用户账号做演示。
2. **关闭连接时序缺口。** 联合检查客户端A-02与[协议层P-04](/reviews/singlink-protocol#p-04)，确认关闭返回后不再产生旧连接状态或代理写入。
3. **建立正式发布身份。** 新环境生成产物，核对签名证书、来源版本和哈希；普通代码贡献流程不能读取正式签名秘密。
4. **补齐平台与工具测试。** 验证权限拒绝、睡眠唤醒、进程死亡、换网、到期/撤销及真实网络路径；在兼容环境重新运行竞态检测，并处理截图基线与DLL清理问题。

此外，报告提出固定协议依赖与构建动作、限制发布版开发库搜索后备、明确连接警告和限制未完成DNS工作等加固建议。这些是后续检查方向，不应全部计成已经证实的远程漏洞。

### 复测记录

| 日期 | 记录 | 状态 |
| --- | --- | --- |
| 2026-11-13 | 提供的v1.0报告：指定App与协议依赖的源码审查及有限本地验证 | 3项App发现未修复 |
| 后续版本 | 需新增修复commit、平台、测试证据及剩余限制 | 尚无复测证据，不标记已修复 |

“未修复”描述的是报告固定快照及其证据状态，不是在持续监控当前主分支。主分支提交有变化，也不能直接推断这些问题已经修复；需核对具体补丁并取得复测证据。本文不声称维护者已经回复或接受评级。公开前应确认问题披露范围和维护者沟通状态。

## 常见问题

### 开源就代表安全了吗？

不代表。开源让实现和版本可检查，但仍需要构建溯源、秘密存储、平台测试和问题修复。当前正式客户端与第一代开源原型也不能混为一谈。

### 两项中危是否说明已经发生用户数据泄漏？

不是。A-01确认存储行为，A-03确认签名配置；没有真实账户被盗、公开产物被伪造或生产数据泄漏的证据。风险必须连同前提与验证方法一起阅读。

### 未发现已知依赖漏洞，是否可以直接上线？

不可以据此判断。已知公告查询只针对特定版本和当时的数据库，不排除未知缺陷、原生平台问题或发布流程缺口。

### 这份报告证明当前星连VPN的速度或无日志政策吗？

不能。商用服务、真实节点和当前已安装应用不在本次范围；本地功能计时不能用于速度排名，源码检查不能替代运营日志审查。

### 怎么引用本页才准确？

建议注明“VPNDevelop开源项目审查与分析”、本页标题、App完整commit、协议依赖commit、具体问题ID和访问日期。引用测试结果时应保留本地验证条件和未覆盖平台，不应改写为对商业产品的安全认证。


## 来源

- [星连第一代开源App：固定版本与项目边界](https://github.com/SingLinkLabs/singlink-vpn-app/blob/0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68/README.md)
- [A-01：Profile中的完整链接序列化](https://github.com/SingLinkLabs/singlink-vpn-app/blob/0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68/lib/models/profile.dart#L75-L92)
- [A-01：AppStore持久化实现](https://github.com/SingLinkLabs/singlink-vpn-app/blob/0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68/lib/core/app_store.dart)
- [A-02：连接与关闭状态控制](https://github.com/SingLinkLabs/singlink-vpn-app/blob/0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68/lib/core/client_controller.dart)
- [A-03：Android发布签名配置](https://github.com/SingLinkLabs/singlink-vpn-app/blob/0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68/android/app/build.gradle.kts#L48-L54)
- [固定版本构建流程](https://github.com/SingLinkLabs/singlink-vpn-app/blob/0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68/.github/workflows/build.yml)
- [官方安全问题报告说明](https://github.com/SingLinkLabs/singlink-vpn-app/blob/0cd87de00d3d3d972d4c39dcdf0fc03b95d14f68/SECURITY.md)
- [本报告使用的协议固定版本](https://github.com/SingLinkLabs/singlink-protocol/tree/6540bf335d0b370453421dabebafc2d1fc8840ea)

本文件为简体中文整理版，不是原始审计报告，也不包含原始日志、源码或复现脚本。
