sentinelden/xcprivacy-lint
GitHub: sentinelden/xcprivacy-lint
一个通过静态分析 Mach-O 二进制来校验 iOS 隐私清单声明与实际 API 调用是否一致的开源工具。
Stars: 0 | Forks: 0
# xcprivacy-lint
[](https://github.com/sentinelden/xcprivacy-lint/actions/workflows/ci.yml)
[](LICENSE)
[](https://swift.org)
```
$ xcprivacy-lint MyApp.ipa
xcprivacy-lint 0.1.0 · checking MyApp.ipa
[ERROR] Missing required declaration: NSPrivacyAccessedAPICategoryFileTimestamp
Triggered by symbol `getattrlist` (called in __TEXT section).
Add the category with reason 3B52.1 or C617.1 to your manifest.
[ OK ] NSPrivacyAccessedAPICategorySystemBootTime — declared with reason 35F9.1.
```
## 为什么需要
自 iOS 17 起,每款 iOS 应用都必须附带一份 `PrivacyInfo.xcprivacy` 清单,声明其对 Apple 必填原因 API 类别的使用情况。Apple 的审核人员会在提交时发现缺失的声明并拒绝构建——这是一个长达 24 小时以上的反馈循环,而且你是在推送到 TestFlight *之后*才会发现。
`xcprivacy-lint` 在本地闭合了这个循环:它会扫描你的 `.app`、`.ipa`、`.xcframework` 或 `.xcarchive`,将二进制文件的 API 接口与清单进行比较,并在 10 秒内报告结果。
## 状态
**v0.1 之前的脚手架阶段。** 设计和骨架已就绪;请参阅 [`DESIGN.md`](./DESIGN.md)。欢迎贡献。
## 安装(未来状态 — 尚未发布)
```
brew install sentinelden/tap/xcprivacy-lint
```
目前,请从源代码构建:
```
git clone https://github.com/sentinelden/xcprivacy-lint
cd xcprivacy-lint
swift build -c release
./.build/release/xcprivacy-lint --help
```
## 用法
```
# 在提交前验证 TestFlight 构建。
xcprivacy-lint ~/Builds/MyApp-1.2.3.ipa
# 分布式 framework 的逐 slice 验证。
xcprivacy-lint ./build/MySDK.xcframework
# CI 模式:machine-readable、fail-on-findings。
xcprivacy-lint --format json --strict MyApp.ipa
# GitHub Actions annotations。
xcprivacy-lint --format gh ./build/MyApp.app
```
### 退出码
| 代码 | 含义 |
|------|---------|
| `0` | 干净 —— 无发现 |
| `1` | 仅有软性发现(过度声明的类别) |
| `2` | 硬性发现 —— 将导致 App Store 审核不通过 |
| `64` | 用法/参数错误 |
| `65` | 无法解析的输入 |
## 它会检查什么
针对 Apple 的每个[必填原因 API 类别](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api):
- **缺失声明** —— 二进制文件调用了某个类别的符号,但清单未声明该类别。硬性发现(Apple 会拒绝)。
- **过度声明** —— 清单声明了某个类别,但二进制文件未触及任何匹配的符号。软性警告。
- **无效的原因代码** —— 清单声明了对该类别无效的原因代码。硬性发现。
目前支持的类别:
- `NSPrivacyAccessedAPICategoryFileTimestamp`
- `NSPrivacyAccessedAPICategorySystemBootTime`
- `NSPrivacyAccessedAPICategoryDiskSpace`
- `NSPrivacyAccessedAPICategoryActiveKeyboards`
- `NSPrivacyAccessedAPICategoryUserDefaults`
符号到类别的映射关系位于 [`Sources/XCPrivacyLintCore/Resources/symbols.yaml`](./Sources/XCPrivacyLintCore/Resources/symbols.yaml)。随着 Apple 发布新类别,只需对该文件提交 PR 即可进行更新——无需更改 Swift 代码。
## 它不会做什么
- **动态分析。** 不生成进程,不附加调试器,不进行运行时观察。Apple 使用的是静态分析;匹配其接口就足够了。
- **通用的 iOS 隐私合规性评分。** 仅提供发现结果,没有“你得了 87%”之类的评分。
- **替代 Apple 的提交验证器。** 我们能很好地近似模拟,以在提交前捕获常见错误;但 Apple 具有最终权威。
有关完整的非目标列表,请参阅 [`DESIGN.md` §3](./DESIGN.md#3-non-goals)。
## CI 集成
```
# .github/workflows/ci.yml
- name: Validate PrivacyInfo.xcprivacy
run: |
brew install sentinelden/tap/xcprivacy-lint
xcprivacy-lint --format gh --strict ./build/MyApp.app
```
`--format gh` 会发出 GitHub Actions 注解,供工作流 UI 消费。`--strict` 使得过度声明也会像缺失声明一样以非零状态码退出。
## 架构
简要说明;完整版本请参阅 [`DESIGN.md`](./DESIGN.md)。
```
target (.app / .ipa / .xcframework / .xcarchive)
│
▼
[Mach-O parser] → symbol table + ObjC class/method refs
│
▼
[Symbol → category map] (Resources/symbols.yaml)
│
▼
required-category set
│
[PrivacyInfo parser] → declared-category set ──┐
├─→ diff → findings
required-category set ┘
│
▼
[Reporter: text | json | gh-actions]
```
三个可独立测试的层:输入提取、静态分析核心(`XCPrivacyLintCore` 库)和报告渲染。
## 许可证
MIT。请参阅 [`LICENSE`](./LICENSE)。
## 构建者
[Sentinel Den](https://sentinelden.com) —— 来自不列颠哥伦比亚省温哥华的 iOS 安全研究和运行时防御 SDK。我们推出了四款商业 iOS SDK([SentinelSDK](https://sentinelden.com/sdk/sentinel)、[CryptoShield](https://sentinelden.com/sdk/cryptoshield)、[AgenticGuard](https://sentinelden.com/sdk/agenticguard)、[EnclaveVault](https://sentinelden.com/sdk/enclavevault))以及 [Sentinel Studio](https://sentinelden.com/studio) macOS 审计工具。xcprivacy-lint 是我们的开源侧翼——秉持同样的工程严谨性,采用 MIT 许可。
标签:API声明验证, App Store审核, iOS开发, IPA解析, Mach-O, PrivacyInfo.xcprivacy, Swift, TestFlight, xcframework, 二进制分析, 云安全监控, 云安全运维, 代码审查, 威胁情报, 安全合规, 开发者工具, 符号分析, 网络代理, 隐私清单, 静态分析