使用原生代码

OWASP 类别: MASVS-CODE:代码质量

概述

Android 应用可以利用用 C 和 C++ 等语言编写的原生代码来实现特定功能。但是,当应用使用 Java 本地接口 (JNI) 与此原生代码交互时,它可能会使自身暴露于漏洞,例如缓冲区溢出和其他可能存在于原生代码实现中的问题。

影响

尽管具有非常积极的影响,例如性能优化和混淆,但在 Android 应用中使用原生代码可能会对安全性产生负面影响。C/C++ 等原生代码语言缺乏 Java/Kotlin 的内存安全特性,这使得它们容易受到缓冲区溢出、使用后释放错误和其他内存损坏问题等漏洞的影响,从而导致崩溃或任意代码执行。此外,如果原生代码组件中存在漏洞,则即使其余部分以 Java 安全编写,它也可能危及整个应用。

缓解措施

开发和编码指南

  • 安全编码指南:对于 C/C++ 项目,请遵守既定的安全编码标准(例如,CERT、OWASP)以降低缓冲区溢出、整数溢出和格式字符串攻击等漏洞的风险。优先考虑以质量和安全性而闻名的库,例如 Abseil。在可能的情况下,考虑采用 Rust 等内存安全的语言,这些语言提供的性能与 C/C++ 相当。
  • 输入验证:严格验证从外部来源接收的所有输入数据,包括用户输入、网络数据和文件,以防止注入攻击和其他漏洞。

强化编译选项

通过激活堆栈保护(Canary)、重定位只读(RELRO)、数据执行保护(NX)和位置无关可执行文件(PIE)等保护机制,可以强化使用 ELF 格式的原生库以抵御各种漏洞。方便的是,Android NDK 编译选项默认已启用所有这些保护。

要验证二进制文件内这些安全机制的实现,您可以使用 hardening-checkpwntools 等工具。

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 等关键词进行网络搜索可以揭示关键的安全信息。

资源