返回介绍

12.2 APP 开发安全

发布于 2024-10-11 22:28:31 字数 6054 浏览 0 评论 0 收藏 0

APP 应用安全,除了我们所熟知的 APP 加壳外,还有一些是应用程序本身的安全问题,例如组件安全、端口安全、数据安全等,甚至还有一些跟业务场景相关的。这里我们说一下 APP 开发中经常遇到的问题与相应对策。

12.2.1 AndroidManifest 配置安全

每个 Android 应用的根目录中都必须包含一个 AndroidManifest.xml 文件。Manifest 文件为 Android 系统提供有关应用的基本信息,系统必须获得这些信息才能运行任意应用代码。此外,Manifest 文件还可执行以下操作:

·为应用的 Java 软件包命名。软件包名称充当应用的唯一标识符。

·描述应用的各个组件,包括构成应用的 Activity、服务、广播接收器和内容提供程序。为实现每个组件的类命名并发布其功能。根据这些声明,Android 系统可以了解这组件具体是什么,以及在什么条件下可以启动它们。

·确定将托管应用组件的进程。

·声明应用必须具备哪些权限才能访问 API 中受保护的部分并与其他应用交互。

·声明其他应用与该应用组件交互所需具备的权限。

·列出 Instrumentation 类,这些类可在应用运行期间提供分析和其他信息。这些声明只会在应用处在开发和测试阶段时出现在清单文件中,在应用发布之前会被删除。

·声明应用所需的最低 Android API 级别。

·列出应用必须链接的库。

我们所熟知的导出组件,是 Android 上最常见也是门槛最低的攻击入口,如 Manifest 中组件设置不当的话,就存在被任意调用的可能。此外,在 Manifest 配置文件中,还有一些可被调试的程序、可被导出的应用数据以及与 Scheme 相关的配置开关,一旦开启就会存在一些风险,笔者将常见的风险与对策整理成表格供读者参考,如表 12-1 所示。

表 12-1 Manifest 配置不当类风险与对策

12.2.2 Activity 组件安全

Activity 组件是 Android 四大组件中用户唯一能够看见的组件,作为软件所有功能的显示及与用户交互的载体,其安全性不言而喻。除了前面说的组件导出暴露问题外,主要是访问权限控制和被劫持问题。

当 Activity 组件需要被外部特定程序调用时,建议使用 android:permission 属性来指定一个权限字符串。

在启动 Activity 时,加入标志位 FLAG_ACTIVITY_NEW_TASK,就能使该 Activity 置于栈顶立即呈现给用户。恶意软件可以监控目标 Activity,侦测到目标 Activity 启动后,立即弹出一个与该应用界面相同的 Activity,实现伪装目标 Activity,也就是我们所说的“被劫持”问题。针对 Activity 劫持目前没有特别好的办法彻底解决,一个思路是在 APP 一些关键界面(比如登录界面)被覆盖时弹出一些提示信息,进入后台的时候判断是不是用户自己触发,如果不是也弹出提示信息。

12.2.3 Service 组件安全

Service 组件是 Android 系统中的后台进程,主要的功能是在后台进行一些耗时的操作。

建议私有 Service 不定义 intent-filter 并且设置 exported 为 false,需要被同公司不同 APP 访问时,可以将 protectionLevel 设置为 signature;如果是合作伙伴 APP 访问,需要对其 APP 签名做校验。若存在 Service 返回数据的情况,则需要关注敏感信息泄露风险。

12.2.4 Provider 组件安全

Content Provider 组件是 Android 应用的重要组件之一,管理对数据的访问,主要用于不同的应用程序之间实现数据共享。Content Provider 的数据源不止包括 SQLite 数据库,还可以是文件数据。通过将数据储存层和应用层分离,Content Provider 为各种数据源提供了一个通用的接口。

参见表 12-2,如果在 AndroidManifest 文件中将某个 ContentProvider 的 exported 属性设置为 true,就会产生一些越权访问数据的风险。访问对象的不同结合 App 实现不当,可能会产生数据任意访问、SQL 注入、目录遍历等风险。

1.私有权限定义错误导致数据被任意访问

私有权限定义经常发生的风险是:定义了私有权限,但是根本没有定义私有权限的级别,或者定义的权限级别不够,导致恶意应用只要声明这个权限就能够访问相应的 Content Provider 提供的数据,造成数据泄露。

2.本地 SQL 注入漏洞

当 Content Provider 的数据源是 SQLite 数据库时,如果实现不当,而 Provider 又是暴露的,则可能会引发本地 SQL 注入漏洞。具体来说,Content Provider 的 query() 如果使用拼接字符串组成的 SQL 语句去查询底层的 SQLite 数据库时,容易发生 SQL 注入。

3.目录遍历漏洞

对外暴露的 Content Provider 实现了 OpenFile() 接口,因此其他有相应调用该 Content Provider 权限的应用即可调用 Content Provider 的 OpenFile() 接口进行文件数据访问。但是如果没有进行 Content Provider 访问权限控制和对访问的目标文件的 URI 进行有效判断,攻击者利用“../”实现目录遍历便可访问任意可读文件。更有甚者,在 Openfile() 接口的实现中,如果要访问的文件不存在,就会创建此文件,也就是说还有可能往手机设备可写目录中写入任意数据。

针对以上问题,最重要的是要在 APP 设计开发之前,就要清楚哪些 Provider 的数据是用户隐私数据或者其他重要数据,考虑是否要提供给外部应用使用,如果不需要提供,则应直接在 Manifest 文件中设置为不导出。

注意:

由于 API level 在 17 以下的所有应用的“android:exported”属性默认值都为 true,因此如果应用的 Content Provider 不必导出,建议显式设置注册的 Content Provider 组件的“android:exported”属性为 false。

如果必须要有数据提供给外部应用,则需要做好权限控制,明确什么样的外部应用可以使用,尽量不要提供用户隐私敏感信息。一般来讲,大部分开放的 Provider,都是提供给本公司其他应用使用,一般打包签名 APP 的签名证书是一致的,这样便可以将 Provider 的 ProtectionLevel 设置为 signature。如果是合作方的 APP 来访问,可以将合作方 APP 的签名哈希值预埋在提供 Provider 的 APP 中,提供 Provider 的 APP 要检查请求访问此 Provider 的 APP 的签名,匹配通过了才能访问。

为了避免 SQL 语句,不要使用拼接字符串的形式,可以使用 SQLiteDatabase 类中的参数化查询 query() 方法。

为了防止目录遍历,建议去除 Content Provider 中的 OpenFile() 接口,过滤限制跨域访问,对访问的目标文件路径进行有效判断,过滤“../”等字符串。

12.2.5 BroadcastReceiver 组件安全

BroadcastReceiver 中文被译为广播接收者,用于处理接收到的广播,广播接收者的安全分为接收安全与发送安全两个方面。

1.接收安全

动态注册广播如果仅为应用内部使用,应当将 exported 设置为 false,这样外部应用不能随便发送广播到自身程序中。

如果需要接收外部应用,则需要配置权限,和前面 Provider 的一样,如果是本公司其他 APP,将 ProtectionLevel 设置为 signature;如果是其他合作伙伴的 APP,则除了设置 ProtectionLevel 外还建议避免敏感信息的传递。

2.发送安全

Android 系统提供了两种广播发送方法,即 sendOrderedBroadcast 和 sendBroadcast。

有序广播通过 Context.sendOrderedBroadcast() 来发送,所有的广播接收器优先级依次执行,广播接收器的优先级通过 receiver 的 intent-filter 中的 android:priority 属性来设置,数值越大优先级越高。当广播接收器接收到广播后,可以使用 setResult() 函数来将结果传给下一个广播接收器接收,然后通过 getResult() 函数取得上个广播接收器接收返回的结果。当广播接收器接收到广播后,也可以用 abortBroadcast() 函数让系统拦截下该广播,并将该广播丢弃,使该广播不再传送到别的广播接收器接收。

普通广播是完全异步的,通过 Context 的 sendBroadcast() 方法来发送,消息传递效率比较高,但所有 receivers(接收器)的执行顺序不确定。接收器不能将处理结果传递给下一个接收器,并且无法终止广播 Intent 的传播,直到没有与之匹配的广播接收器为止。

Android 官方在 SDK 文档中说明了一些不安全的 API,包括:sendStickyBroadcast、sendStickyOrderedBroadcast、sendStickyOrderedBroadcastAsUser、sendStickyBroadcastAsUser,建议不要在 APP 使用。

12.2.6 WebView 组件安全

WebView 是一个基于 Webkit 引擎、展现 Web 页面的组件,APP 通过调用该组件就可以访问网页内容,所以有非常多的移动应用都内嵌了 WebView 组件。而在通付盾发布的《2017 年度移动应用安全态势报告》中,与 WebView 组件相关的漏洞是排名前三的,分别是:未移除有风险的 WebView 系统隐藏接口,WebView 远程代码执行安全,WebView 组件忽略 SSL 证书验证错误漏洞,如图 12-2 所示。

图 12-2 Android 移动应用高危漏洞类型分布

WebView 在 Android 应用开发中广泛使用,除了具有一般 View 的属性和设置外,还可对 URL 请求、页面加载、渲染、页面交互进行处理,可谓功能强大。对黑客而言,它是一个非常理想的攻击面,点开一个链接或者扫描一个二维码就会执行恶意代码。在使用 WebView 组件过程中,除了一些系统隐藏接口,还会有一些与本地交互、保存密码、HTTPS 通信认证相关的风险需要关注,为了节省篇幅,笔者整理了一个 WebView 组件常见风险与对策表格,见表 12-2。

表 12-2 WebView 组件相关风险与对策

值得注意的是,Android N 中增加了一个开发者选项,就是在所有的应用中将 Web-View 的渲染进程运行在独立的沙箱中。即使恶意网页通过漏洞在渲染进程中执行了代码,还需要更多的漏洞绕过沙箱的限制。这一特性将在 Android O 中默认启用。但在这一缓解措施正式部署到大部分设备之前,通过攻击 WebView 获得远程代码执行进而直接攻击应用仍然是可行的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文