如何通过编译器标志增强移动应用的安全性

news/2024/12/15 20:46:46/

作为一名 Android 或 iOS 开发者,您可能已经熟悉一些常见的安全开发最佳实践,比如验证外部输入、合理管理内存以及避免使用弱加密算法。然而,即便是最精心编写的代码,也可能包含一些 bug,其中一些可能会导致可被利用的安全漏洞,尤其是在使用 C 或 C++ 等语言编写的原生代码中。

多年来,开发了许多防御技术,可以通过简单的编译器标志来启用,而无需修改源代码。这些技术能够有效地提高应用的安全性。在本文中,我们将为您概述一些关键的安全特性,包括:

· 它们防护的攻击类型

· 如何启用这些特性(步骤指南)

· 它们在 Android 和 iOS 上的适用性

· 如何为不同平台设置编译器标志

为 Android 和 iOS 设置编译器标志

在深入探讨具体的安全特性之前,我们先简要回顾一下如何在 Android 和 iOS 上设置这些编译器标志。如果您已经熟悉这些操作,可以跳过这一部分!

Android

通常,Android 应用的原生代码通过 ndk-build 脚本或结合 Gradle 使用 CMake 进行编译。在 ndk-build 的情况下,可以通过在 Application.mk 文件中添加新的标志来启用:

如果您使用的是 Gradle 配合 CMake,则可以在 build.gradle 文件中添加编译器标志:

iOS

在 iOS 中,您可以通过 Xcode 项目的“Build Settings”选项卡来设置编译器标志:

1. 在“Project Navigator”中选择您的项目文件。

2. 转到目标的“Build Settings”选项卡。

3. 在“Other C Flags”或“Other C++ Flags”部分添加所需的标志。

编译器相关的安全特性

1. 栈保护(Stack Canaries)

栈保护是一种防御缓冲区溢出攻击的基础技术。缓冲区溢出攻击发生时,攻击者通过溢出栈上的缓冲区,可能会覆盖函数的返回地址,从而执行任意代码,造成严重的安全漏洞,例如未经授权的访问或系统崩溃。启用栈保护(通过 -fstack-protector-strong 编译器标志)可以有效避免这类攻击。

· 适用于 Android: ✅

· 适用于 iOS: ✅

如果您想进一步了解该主题,可以查阅 Wikipedia 上关于缓冲区溢出保护的文章,或者阅读经典的《Smashing The Stack For Fun And Profit》一文。

2. 指针认证(Pointer Authentication,PAC)

指针认证(PAC)通过加密签名指针,尤其是返回地址和函数指针,以防止控制流攻击。若指针被篡改,验证失败,攻击将被阻止。这个特性依赖于特定的硬件支持,这可能会使设备的兼容性成为问题。但幸运的是,目前所有支持的 iOS 设备都已支持 PAC,而 Android 编译器会确保只使用在旧设备上不执行任何操作的指令。

· 适用于 Android: ✅

· 适用于 iOS: ✅

如何在 Android 上启用 PAC:

· 使用 ndk-build 时:在每个 Android.mk 文件中设置 LOCAL_BRANCH_PROTECTION := standard

· 使用 Gradle 配合 CMake 时:添加 -mbranch-protection=standard 编译器标志

在 PAC 的基础上,Google 还建议启用控制流完整性(CFI)。您可以在 LLVM 的官方网站上了解更多关于 CFI 的信息。

如何在 iOS 上启用 PAC:

在 Xcode 的构建设置中,将 arm64e 目标添加到“Architectures”部分。由于 Apple 控制硬件和软件,它可以为所有设备提供一致的 PAC 实施,而 Android 平台则需要根据设备硬件特性通过编译器标志来启用 PAC。

更多信息可以参考 Apple 的文章,了解如何为应用启用指针认证。

3. 只读重定位(Relocation Read-Only,RelRO)

RelRO 是一种保护应用免受内存篡改攻击的机制。它通过在初始化完成后将某些内存区域标记为只读来工作。特别是,它可以保护全局偏移表(GOT),该表用于管理应用程序中的动态链接函数。通过将 GOT 和其他关键区域标记为只读,RelRO 可以防止攻击者修改这些指针,从而劫持应用程序的执行流。

· 适用于 Android: ✅

· 适用于 iOS: ❌(iOS 没有 GOT 结构)

RedHat 博客有一篇很好的文章,详细介绍了 RelRO 的更多信息。

确保您的移动应用安全

确保您的应用安全不仅仅是编写安全代码,还需要采取综合措施,包括加强原生代码的构建过程。启用上述提到的编译器标志可以帮助您实现这一目标,降低常见攻击带来的风险,而且不会对性能造成显著影响。然而,建立安全的构建过程并不是一次性的任务,它需要持续的监控。在应用程序不断演进的过程中,确保这些安全配置始终保持有效非常重要。通过将 MAST(移动应用安全测试)工具集成到 CI 流水线中,您可以自动化地测试最终产品的安全性,捕捉构建设置中的回归问题,避免将不安全的应用发布给用户。


http://www.ppmy.cn/news/1555402.html

相关文章

数据结构 ——二叉树转广义表

数据结构 ——二叉树转广义表 1、树转广义表 如下一棵树&#xff0c;转换为广义表 root(c(a()(b()()))(e(d()())(f()(j(h()())())))) (根&#xff08;左子树&#xff09;&#xff08;右子树&#xff09;) 代码实现 #include<stdio.h> #include<stdlib.h>//保存…

Scala记号字面值 空白与注释

记号字面值 语法&#xff1a; symbolLiteral :: „‟‟ idrest 记号字面值‟x 是表达式 scala.Symbol(“x”)的简写形式。Symbol 是一个 case 类(5.3.2)&#xff0c;定义如下&#xff1a; package scala final case class Symbol private (name: String) { override def toStri…

每天40分玩转Django:Django模型

Django框架学习第2天&#xff1a;Django模型 一、课程概述 学习项目具体内容预计用时模型定义模型类编写、字段类型、关系类型90分钟ORM操作增删改查、高级查询、聚合函数90分钟数据库迁移迁移命令、迁移文件、数据导入导出60分钟 二、模型定义 2.1 基本模型结构 # blog/mo…

【数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;编写一个程序实现单链表的基本运算。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;初始化线性表、销毁线性表、判定是否为空表、求线性…

使用idea创建一个JAVA WEB项目

文章目录 1. javaweb项目简介2. 创建2.1 idea新建项目2.2 选择&#xff0c;命名2.3 打开2.4 选择tomcat运行2.5 结果 3. 总结 1. javaweb项目简介 JavaWeb项目是一种基于Java技术的Web应用程序&#xff0c;主要用于开发动态网页和Web服务。这种项目能够构建在Java技术栈之上&a…

使用 UniApp 实现简单的个人中心页面

1. 创建 UniApp 项目 首先&#xff0c;确保你已经安装了 HBuilderX 或其他支持 UniApp 的开发工具。然后创建一个新的 UniApp 项目。 # 使用 HBuilderX 创建新项目 # 选择 uni-app 模板 -> 选择 Vue.js 模板 -> 输入项目名称 -> 创建2. 安装依赖 UniApp 内置了一些…

交流负载箱的安全事项和注意事项有哪些?

交流负载箱用于模拟实际负载的电气设备&#xff0c;广泛应用于电力系统、通信系统、自动化控制系统等领域。在使用过程中&#xff0c;为确保人身和设备安全&#xff0c;需要注意以下安全事项和注意事项&#xff1a; 选择合适的交流负载箱&#xff1a;根据实际需求选择合适的交…

Python生成对抗神经网络GAN预测股票及LSTMs、ARIMA对比分析ETF金融时间序列可视化

全文链接&#xff1a;https://tecdat.cn/?p38528 本文聚焦于利用生成对抗网络&#xff08;GANs&#xff09;进行金融时间序列的概率预测。介绍了一种新颖的基于经济学驱动的生成器损失函数&#xff0c;使 GANs 更适用于分类任务并置于监督学习环境中&#xff0c;能给出价格回…