ReadViewSDK/Doc/CONCERNS.md

122 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 代码库风险与关注点
**分析日期:** 2026-05-21
## 高风险:安全与隐私
### 1) CocoaPods 构建关闭了 User Script Sandboxing
- **问题:** `post_install` hook 将 Pods *以及* 用户工程的 `ENABLE_USER_SCRIPT_SANDBOXING` 强制设置为 `NO`
- **影响:** 削弱对内嵌 Web 内容的纵深防御;增加 `WKWebView` 相关功能的风险面,并可能不符合组织/审核(含 App Store安全基线。
- **建议缓解:**
- 移除全局覆盖,保持系统默认的 sandboxing。
- 如确有依赖需要 workaround仅对具体 Pod target 做最小范围的设置,并记录原因。
- 在 CI 中增加校验:出现 `ENABLE_USER_SCRIPT_SANDBOXING=NO` 时告警/失败。
### 2) 外链打开未做 allowlistscheme/host
- **问题:** EPUB 内容中的外部 URL 通过 `UIApplication.shared.open(...)` 打开时,未对 scheme/host 做校验,也未强制用户二次确认。
- **影响:** 恶意 EPUB 可能触发钓鱼、隐私泄露,或打开意外的 URL scheme包含跳转到其他 App 的 deep link
- **建议缓解:**
- 强制 allowlist默认仅允许 `https`;如需 `mailto`/`tel` 等应在明确 UI 提示后允许)。
- 弹出确认对话框,展示目标 host。
- 对 bridge 消息与导航行为中的非 HTTP(S) scheme 做拒绝/过滤。
### 3) EPUB 解压未显式做 Zip Slip路径穿越加固
- **问题:** 解压逻辑构造 `destinationURL = extractionURL.appendingPathComponent(entry.path)` 并解压 entry但未显式验证标准化后的目标路径是否仍在 `extractionURL` 之内。
- **影响:** 构造的 EPUB 可能尝试通过 `../...` 路径穿越覆盖目标目录外的文件(实际危害与 ZIPFoundation 行为及权限有关,但建议显式防护)。
- **建议缓解:**
- 解压前计算 `standardizedDestination = destinationURL.standardizedFileURL`,并确保其前缀位于 `extractionURL.standardizedFileURL.path + "/"` 之下。
- 拒绝包含 `..`、绝对路径、或异常路径分隔符形式的 entry。
- 考虑先解压到新的随机 UUID 目录,仅将校验通过的内容移动到最终目录。
### 4) 选中文本/高亮内容明文写入 UserDefaults
- **问题:** 选中文本与高亮 payload 以 JSON 编码写入 `UserDefaults`(包含“新”持久化与 legacy 路径)。
- **影响:** 可能将书籍敏感内容(高亮、选择文本)存入默认不加密的持久化位置,可能进入备份;同时数据量可能无限增长(性能与隐私风险)。
- **建议缓解:**
- 仅持久化稳定标识/范围(例如 CFI / rangeInfo运行时再派生文本。
- 如必须持久化文本,存入加密存储(例如 Keychain 或使用 `NSFileProtectionComplete` 的加密文件)并设置大小上限。
- 增加数据保留策略,并提供 “Clear reading data” API。
## 性能与稳定性风险
### 5) Scheme handler 将整文件一次性读入内存(无流式)
- **问题:** `WKURLSchemeHandler` 使用 `Data(contentsOf:)` 读取资源并一次性返回。
- **影响:** EPUB 内的大图/字体/媒体资源可能导致内存峰值、加载变慢,甚至在内存压力下被系统终止。
- **建议缓解:**
- 尽可能改为基于 `InputStream` 的流式传输,并使用增量 `didReceive(...)`
- 对单个资源增加大小上限,超过则优雅失败并提示。
### 6) 隐藏的分页 WKWebView 可能加载外部资源
- **问题:** `RDEPUBPaginator` 使用 `loadFileURL(...allowingReadAccessTo:)`,但未看到对 `navigationAction` 的 allowlist例如仅允许 `file://` 或自定义 `ss-reader://`)。
- **影响:** 分页测量阶段可能产生意外网络请求,引发隐私泄露与不可控性能波动。
- **建议缓解:**
- 在 paginator 场景加入导航策略:默认仅允许 `file://`(以及必要的自定义 scheme`http(s)` 直接取消。
- 视需求考虑内容拦截规则或禁用分页阶段的网络加载。
### 7) EPUB 解压缓存目录可能无限累积
- **问题:** 解压路径基于文件名/大小/mtime 的确定性签名;若目录已存在则直接复用,且无清理策略。
- **影响:** 书籍数量多或频繁更新时磁盘占用持续增长,造成存储压力与潜在卡顿。
- **建议缓解:**
-`ssreaderview-epub` 缓存目录实现淘汰策略LRU/按时间)。
- 提供显式清理 API并在低存储信号时触发清理。
## 可维护性与技术债
### 8) DEBUG 下日志与 Web Inspector 可能泄露内容
- **问题:** Debug 辅助会打印导航/消息体selection payload 可能包含用户选中文本;且 DEBUG 下可能默认开启 inspectable。
- **影响:** 在 debug 构建(含内部测试/QA日志可能包含敏感内容并被导出/分享。
- **建议缓解:**
- 默认对消息体做脱敏(仅记录类型/大小),需要时再显式 opt-in 输出内容。
-`isInspectable` 受控于 app 级 debug 开关,而不是在 DEBUG 下默认启用。
## 构建与依赖脆弱性
### 9) 仓库中包含 vendored 的 `Pods/` 目录
- **问题:** 仓库根目录有 `Pods/`,示例工程内也有 `ReadViewDemo/Pods/`
- **影响:** diff 体积大、clone 慢、易产生 merge 冲突,也容易出现依赖陈旧导致的构建不一致。
- **建议缓解:**
- 通常建议不要提交 Pods仅提交 `Podfile.lock`,在 CI 中执行 `pod install`
- 如确有 vendoring 政策,需文档化并提供同步/校验工具,避免漂移。
### 10) Podfile 与 podspec 的部署版本不一致
- **问题:** `Podfile` 设为 `platform :ios, '15.6'`,而 podspec 声明 `s.platform = :ios, "15.0"`
- **影响:** 对外承诺与本地构建基线不一致,容易造成集成方预期偏差。
- **建议缓解:**
- 对齐 `Podfile`、`*.podspec`、Xcode project 的 deployment target。
- 在 CI 中增加漂移检查,防止版本被无意改动。
### 11) podspec 将 Swift 版本钉死为 5.10
- **问题:** `s.swift_versions = ["5.10"]` 将 pod 与特定 Swift 版本强绑定。
- **影响:** 旧工具链的集成方无法使用;未来升级可能出现“突然不兼容”,尤其当依赖未同步时。
- **建议缓解:**
- 如兼容性允许,可声明更多支持版本(或范围),并在 CI 中覆盖多个 Xcode/Swift 版本构建验证。
- 在文档中明确最低支持的 Xcode/Swift 版本。
## 不清晰/容易踩坑的契约
### 12) 默认的持久化协议实现可能静默丢失数据
- **问题:** `RDEPUBReaderPersistence` 通过 protocol extension 提供了 bookmarks/settings 的默认 no-op 实现。
- **影响:** 集成方可能误以为这些能力默认会持久化,但实际数据会被静默丢弃,且不易排查。
- **建议缓解:**
- 将关键方法改为必须实现(移除 no-op 默认实现);或在未实现且功能启用时输出日志/assert。
- 提供并文档化 “最小持久化” 与 “完整持久化” 的参考实现。
---
## Evidence仓库路径
- Build flags`Podfile`
- Pod metadata/toolchain`RDReaderView.podspec`
- Archive extraction`Sources/RDReaderView/EPUBCore/RDEPUBParser+Archive.swift`
- Resource path validationpost-extraction`Sources/RDReaderView/EPUBCore/RDEPUBParser+Resources.swift`
- Scheme handler reads full file bytes`Sources/RDReaderView/EPUBCore/RDEPUBResourceURLSchemeHandler.swift`
- WebView bridge + message handling`Sources/RDReaderView/EPUBCore/RDEPUBWebView+JavaScriptBridge.swift`
- External link opening`Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift`
- UserDefaults persistence implementation`Sources/RDReaderView/EPUBUI/RDEPUBReaderPersistence.swift`
- Hidden paginator web view`Sources/RDReaderView/EPUBCore/RDEPUBPaginator.swift`
- Debug logging`Sources/RDReaderView/EPUBCore/RDEPUBWebViewDebug.swift`
- Vendored dependencies`Pods/`、`ReadViewDemo/Pods/`
---
*风险与关注点审计2026-05-21*