ReadViewSDK/Doc/CONCERNS.md

7.9 KiB
Raw Blame History

代码库风险与关注点

分析日期: 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://(以及必要的自定义 schemehttp(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 flagsPodfile
  • Pod metadata/toolchainRDReaderView.podspec
  • Archive extractionSources/RDReaderView/EPUBCore/RDEPUBParser+Archive.swift
  • Resource path validationpost-extractionSources/RDReaderView/EPUBCore/RDEPUBParser+Resources.swift
  • Scheme handler reads full file bytesSources/RDReaderView/EPUBCore/RDEPUBResourceURLSchemeHandler.swift
  • WebView bridge + message handlingSources/RDReaderView/EPUBCore/RDEPUBWebView+JavaScriptBridge.swift
  • External link openingSources/RDReaderView/EPUBUI/RDEPUBReaderController.swift
  • UserDefaults persistence implementationSources/RDReaderView/EPUBUI/RDEPUBReaderPersistence.swift
  • Hidden paginator web viewSources/RDReaderView/EPUBCore/RDEPUBPaginator.swift
  • Debug loggingSources/RDReaderView/EPUBCore/RDEPUBWebViewDebug.swift
  • Vendored dependenciesPods/ReadViewDemo/Pods/

风险与关注点审计2026-05-21