OWASP 类别: MASVS-CODE: 代码质量
概览
Android 应用可以利用以 C 和 C++ 等语言编写的原生代码来实现特定功能。然而,当应用使用 Java Native Interface (JNI) 与此原生代码交互时,可能会暴露自身于原生代码实现中可能存在的漏洞,例如缓冲区溢出和其他问题。
影响
尽管在性能优化和混淆等方面带来了积极影响,但在 Android 应用中使用原生代码可能会产生负面安全影响。C/C++ 等原生代码语言缺乏 Java/Kotlin 的内存安全特性,容易受到缓冲区溢出、释放后使用错误和其他内存损坏问题的影响,从而导致崩溃或任意代码执行。此外,如果原生代码组件中存在漏洞,即使应用的其余部分以安全的方式用 Java 编写,也可能危及整个应用。
缓解措施
开发和编码指导
- 安全编码指南:对于 C/C++ 项目,请遵循既定的安全编码标准(例如 CERT、OWASP),以缓解缓冲区溢出、整数溢出和格式字符串攻击等漏洞。优先使用以质量和安全性著称的库,例如 Abseil。在可能的情况下,考虑采用像 Rust 这样的内存安全语言,它提供与 C/C++ 可比的性能。
- 输入验证:严格验证从外部源接收到的所有输入数据,包括用户输入、网络数据和文件,以防止注入攻击和其他漏洞。
加固编译选项
使用 ELF 格式的原生库可以通过激活栈保护 (Canary)、重定位只读 (RELRO)、数据执行预防 (NX) 和位置无关可执行文件 (PIE) 等保护机制来抵御一系列漏洞。方便的是,Android NDK 编译选项默认已启用所有这些保护措施。
要验证二进制文件中这些安全机制的实现情况,您可以使用 hardening-check
或 pwntools
等工具。
Bash
$ pwn checksec --file path/to/libnativecode.so
Arch: aarch64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
验证第三方库没有漏洞
在选择第三方库时,优先使用在开发社区中享有良好声誉的库。像 Google Play SDK Index 这样的资源可以帮助您识别评价良好且值得信赖的库。确保将库更新到最新版本,并使用 Exploit-DB 等数据库等资源主动搜索与之相关的任何已知漏洞。使用 [library_name] vulnerability
或 [library_name] CVE
等关键词进行网络搜索,可以发现关键的安全信息。
资源
- CWE-111: 不安全 JNI 的直接使用
- 漏洞利用数据库
- 检查二进制文件的安全加固特性
- 使用 pwntools 检查二进制安全设置
- Linux 二进制安全加固
- 使用重定位只读 (RELRO) 加固 ELF 二进制文件
- OWASP 二进制保护机制
- SEI CERT 编码标准
- OWASP 开发者指南
- Google Play SDK 索引
- Android NDK
- Android Rust 简介
- Abseil (C++ 常用库)
- PIE 由链接器强制执行