Securely Developing on Mobile

简介: More than ever, people are using their mobile device as their primary means of accessing the Internet.

More than ever, people are using their mobile device as their primary means of accessing the Internet. This provides not only unparalleled access to information, but also millions upon millions of applications built by third party developers. This platform approach enables users to experience great apps built by developers both large and small. However, this decentralized platform approach only works if there are strong, industry-wide best practices around important app basics such as security. For this reason, we applaud the Federal Trade Commission for hosting its Public Forum on Threats to Mobile Devices and thank them for including Facebook in this important meeting.


For everyone who couldn’t make the forum yesterday, we have documented some of the best practices for developing on Android and iOS, and we're excited to share them with other developers.


From the outset, it is important to note that making apps that are secure on Android and iOS is hard. When your application behaves in manner that is unintended, it creates security and privacy implications for the end user, and this might not be restricted to the confines of your app, but potentially across the device. 


Top risks include malware installed on the phone alongside your app, tools that allow malicious actors to snoop on device activity, and even malicious websites that can trigger actions in your app using custom URL schemes.


The only way to ensure that your application is secure is to engineer your application for security from the ground up.


Here are some recommendations to reduce vulnerabilities in your application:


1. Use HTTPS in a secure way

HTTPS can help you protect the privacy of user data against a man-in-the-middle attack, which could manifest as snooping on data and stealing user sessions on the network. 


However, to obtain this protection your app needs to perform several steps to verify the server to which it is connecting, and this process is very error-prone. Even a small mistake in verification can result in no protection at all. Read more here - http://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html


Android

Instead of using the SSLSocketFactory classes, you should use APIs like HttpsURLConnection, which are simpler to use and perform the correct verification steps on your behalf. HttpsURLConnection also adds features (including TLS tickets and SNI headers, which only work correctly after Jellybean) to the HTTPS connection that gives you better performance than using raw SSL sockets. It should always be better to use this API. 


iOS

Similarly, on iOS it is preferable to always use the high level API NSURLConnection for network requests. Lower level APIs such as CFStream need explicit and often error-prone configuration of SSL.


Android and iOS

To debug network requests with a proxy, such as Charles, you may prefer manually installing a SSL certificate in your testing device rather than using preprocessor variables and debug-only code to deactivate SSL validation. See more - http://www.charlesproxy.com/documentation/faqs/ssl-connections-from-within-iphone-applications/


2. There are No Client Secrets

Often, developers will spend time trying to obfuscate secrets in the application, which will be used to either authenticate their app to their server or to perform a client-side OAUTH flow.


Trying to obfuscate a secret in Android and iOS clients is a futile effort as the secrets can always be recovered using the abundance of reverse-engineering and debugging tools available for APKs (https://code.google.com/p/android-apktool/), Java (http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler)), and Objective C (http://www.fscript.org/).


a. Authenticating an app to your server

Often the goal of authenticating the app to the server is to prevent users from getting phished. A good solution to phishing is to support a two-factor authentication for your application. Facebook login approvals (https://www.facebook.com/note.php?note_id=10150172618258920) is an example of a large scale two-factor authentication solution that millions of people use daily.


b. OAUTH

Do not expose your OAUTH secrets to the world via your client application. Store the OAUTH secrets on your server so that they are indeed secret. To obtain an OAUTH token, the client would then request an end-point on your server that could proxy the token request to the OAUTH provider with the secret, and then, return the token to the client. Once the client obtains the OAUTH token, it can directly make requests to the OAUTH provider.


3. WebViews


Android

Some applications use Android WebViews and store cookies in the WebViews to access the remote servers. 


You should restrict the web-pages that can load inside your WebView with a whitelist. If you are only going to open pages from your domain in the WebView you should restrict those. 


This will prevent others from triggering the loading of local resources such as javascript:// urls and file:// urls, which can be used to XSS users on Android. (Read more here – (http://www.80vul.com/android/android-0days.txt)


iOS

In the simple case, a UIWebView is just a web browser tab sharing its cookie storage with the app. However, more complex interactions are often needed between the embedded JavaScript and the app. This is usually done by having the app catch and interpret URLs of a special scheme in the outgoing requests of the WebView.


These interactions must be carefully reviewed. In particular,

a. if the webview is meant to browse the web, it should not be given large privileges over the native app;

b. if they include user-controlled strings (this typically includes the initial URL and any string injected in the Javascript environment using stringByEvaluatingJavaScriptFromString) make sure to sanitize the native inputs of webviews


4. Tap-Jacking


Android

Other applications can overlay content over your application, and fool users into clicking buttons on your app underneath.


To prevent this consider setting the setFilterTouchesWhenObscured (http://developer.android.com/reference/android/view/View.html#setFilterTouchesWhenObscured) property to true in your views. This will prevent your application from getting touches when another application is obscuring it.


iOS

Proofs of concept exist on iOS as well (http://www-personal.umich.edu/~yangqi/pivot/mobile_phishing_defense.pdf) although this issue should concern only jailbroken devices.


5. Race Conditions onInstalling Apps


Permission stealing [Android]

Other apps that are installed before your app, could steal android permissions (including signature level permissions) that you have declared in your manifest by declaring them before you.


Your app will function normally, but as a result of this, malware that steals permissions could snoop into all of your app's content providers and other components. 


To prevent this, reduce both the exposure of components and also explicitly authenticate the callers of your components. 


Stealing of URL schemes [iOS]

Except for a core subset managed by iOS, URL schemes are registered on first-come, first-served basis.


6. Controlling Exposed Features


Activities, services and broadcast receivers  [Android]

You should aim to expose as little of your application as possible to other applications that are potentially malicious. Not setting intent-filters on components, or explicitly setting "exported=false," will cause components to be local to your application. This is the most effective way of protecting components.


Make sure that before any action that changes the state of your app is taken, the user performs a UI action like clicking a button (this is analogous to CSRF protection in web applications). It is dangerous to perform a write action based on an intent extra passed into a component.


Exposed URL schemes [iOS]

Similarly, iOS apps should not perform state-changing actions on processing URLs without asking for confirmation from the user.


7. Watch Out for Internal URL Schemes.

In addition to exposed URL schemes, it is common to define custom URL schemes internally to an iOS or Android app so as to let trusted sources trigger specific actions.


Android

When using custom URL schemes in intent filters, be cognizant of the fact that they can be triggered by not only apps installed on the device, but also malicious websites that the user opens in the browser by simply clicking on a link. This triggers an ACTION_VIEW intent for the URL that was clicked, so that the user does not need to install malware for the malware to exploit a particular component if it has another vulnerability.


iOS

Make sure to distinguish internal URLs created by trusted sources from public URLs callable by external apps or made clickable in user contents. The library class NSDataDetector does not restrict the schemes of URLs detected in user contents.


8. Authenticating Callers of Components

 

Android

a. Activities

Consider calling activities that need to know their caller using startActivityForResult(). The calleeActivity can then enforce the identity of the caller using getCallingPackage()and ensures that is non-null and the package that it expects. A signature check using PackageManager is the most effective way of ensuring the caller is from the same app family as the callee.


b. Content Providers

The user id of the caller can be obtained using Binder.getCallingUid(), and can be used for permission enforcement via signature checks.


c. Broadcast Receivers

There is no current way to get the identity of the initiator of the broadcast. For system broadcasts, ensure that you check the action string of the incoming intent to make sure an intent is coming from the system. 


d. Services

Services can enforce the callerusing Binder.getCallingUid() and using signature checks. However services using the messaging IPC mechanism cannot get the caller uid in the handleMessage() callback. Consider using AIDL-based service calls for exposed services.


iOS

Rather than UIApplicationDelegate:application:handleOpenURL:, you may want to implement UIApplicationDelegate:application:openURL:sourceApplication:annotation: and use the sourceApplication to authenticate a URL caller over time. To mitigate spoofing of callers' URL schemes, the Facebook SDK also lets callers to the main app choose an encryption key for their response.


9. Use explicit intents andIntent hijacking [Android]

If private data is being transmitted in an intent, use explicit intents. Explicit intents ensure that the callee receiving the intent will be the one that the caller intended to receive the intent. 


Android provides ways to call components using implicit intents, however, keep in mind implicit intents could allow a malicious application to hijack the intent.


If using implicit intents, you should dynamically resolve the receivers of the intent and perform signature checks before sending the intent. "setPackage" is also an option, which restricts the package that can receive an intent. However, this works only after Ice Cream Sandwich.


10. Open redirects

You could protect all your components with permissions and checks, however if there exists even one component in your application that takes a component as an input and redirects to that component, this could be used to circumvent all checks. Avoid this practice at all costs.


11. SQL injection


Android

SQLLiteQueryBuilder is a standard way of building SQL queries for Android. However even though it seems to be safe against SQL injection attacks, underneath the hood its imply concatenates strings. This allows attackers to insert arbitrary clauses into the SQL statement.


You must carefully sanitize user input strings to content providers that are exposed.


iOS

You should refrain from constructing SQL query strings directly and instead use a more abstract framework such as EGODatabase or FMDB.


12. Language-Based Vulnerabilities[iOS]

Objective C is susceptible to a variety of programming errors that can be exploited:

* C fragments are vulnerable to the classical C vulnerabilities such as buffer overflows.

* Zombie objects may be exploited.

* User-dependent inputs occurring in format strings, selectors, or regular expressions may be exploited.

* It is important to keep in mind that static types appearing in the code are not enforced at runtime.

* Returning nil values on failures and unimplemented selectors is often ok. Yet, unexpected nil values can cause a crash with some library functions, and can yield unpredictable results in general (for instance [nil isEqualToString:nil] == 0).

目录
相关文章
|
3天前
|
人工智能 运维 安全
|
1天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
8天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
770 109
|
3天前
|
机器学习/深度学习 传感器 算法
Edge Impulse:面向微型机器学习的MLOps平台——论文解读
Edge Impulse 是一个面向微型机器学习(TinyML)的云端MLOps平台,致力于解决嵌入式与边缘设备上机器学习开发的碎片化与异构性难题。它提供端到端工具链,涵盖数据采集、信号处理、模型训练、优化压缩及部署全流程,支持资源受限设备的高效AI实现。平台集成AutoML、量化压缩与跨硬件编译技术,显著提升开发效率与模型性能,广泛应用于物联网、可穿戴设备与边缘智能场景。
173 127
|
3天前
|
算法 Python
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
230 152
|
5天前
|
Java 数据库 数据安全/隐私保护
Spring 微服务和多租户:处理多个客户端
本文介绍了如何在 Spring Boot 微服务架构中实现多租户。多租户允许单个应用实例为多个客户提供独立服务,尤其适用于 SaaS 应用。文章探讨了多租户的类型、优势与挑战,并详细说明了如何通过 Spring Boot 的灵活配置实现租户隔离、动态租户管理及数据源路由,同时确保数据安全与系统可扩展性。结合微服务的优势,开发者可以构建高效、可维护的多租户系统。
212 127
|
4天前
|
机器学习/深度学习 存储 资源调度
CMSIS-NN:ARM Cortex-M处理器的高效神经网络内核——论文解读
CMSIS-NN是专为ARM Cortex-M系列微控制器优化的神经网络计算内核库,旨在支持资源受限的物联网边缘设备进行高效的深度学习推理。该库通过对卷积、池化、全连接层等关键操作进行定点量化、SIMD指令优化和内存布局调整,显著提升了模型在嵌入式设备上的运行效率。实验表明,CMSIS-NN在Cortex-M7处理器上的推理速度比基准实现提升了近5倍,大幅降低了功耗,为边缘AI应用提供了可行的技术路径。
224 128