From 2435940aac3620ac4daa7b8aceba8cee8b1b51cc Mon Sep 17 00:00:00 2001 From: Adrian Ludwig Date: Mon, 7 Nov 2011 09:24:23 -0800 Subject: Adding new "Security Best Practices" to the html docs. Change-Id: Iada088b23c4709e9c9212f41724f99f4e0fa393e --- docs/html/guide/practices/security.jd | 772 ++++++++++++++++++++++++++++++++++ 1 file changed, 772 insertions(+) create mode 100644 docs/html/guide/practices/security.jd (limited to 'docs/html/guide/practices') diff --git a/docs/html/guide/practices/security.jd b/docs/html/guide/practices/security.jd new file mode 100644 index 000000000000..5da7e98c6a4c --- /dev/null +++ b/docs/html/guide/practices/security.jd @@ -0,0 +1,772 @@ +page.title=Designing for Security +@jd:body + +
+
+

Android was designed so that most developers will be able to build +applications using the default settings and not be confronted with difficult +decisions about security. Android also has a number of security features built +into the operating system that significantly reduce the frequency and impact of +application security issues.

+ +

Some of the security features that help developers build secure applications +include: +

+ +

Nevertheless, it is important for developers to be familiar with Android +security best practices to make sure they take advantage of these capabilities +and to reduce the likelihood of inadvertently introducing security issues that +can affect their applications.

+ +

This document is organized around common APIs and development techniques +that can have security implications for your application and its users. As +these best practices are constantly evolving, we recommend you check back +occasionally throughout your application development process.

+ + +

Using Dalvik Code

+

Writing secure code that runs in virtual machines is a well-studied topic +and many of the issues are not specific to Android. Rather than attempting to +rehash these topics, we’d recommend that you familiarize yourself with the +existing literature. Two of the more popular resources are: +

+ +

This document is focused on the areas which are Android specific and/or +different from other environments. For developers experienced with VM +programming in other environments, there are two broad issues that may be +different about writing apps for Android: +

+ + +

Using Native Code

+ +

In general, we encourage developers to use the Android SDK for most +application development, rather than using native code. Applications built +with native code are more complex, less portable, and more like to include +common memory corruption errors such as buffer overflows.

+ +

Android is built using the Linux kernel and being familiar with Linux +development security best practices is especially useful if you are going to +use native code. This document is too short to discuss all of those best +practices, but one of the most popular resources is “Secure Programming for +Linux and Unix HOWTO”, available at +http://www.dwheeler.com/secure-programs.

+ +

An important difference between Android and most Linux environments is the +Application Sandbox. On Android, all applications run in the Application +Sandbox, including those written with native code. At the most basic level, a +good way to think about it for developers familiar with Linux is to know that +every application is given a unique UID with very limited permissions. This is +discussed in more detail in the Android Security +Overview and you should be familiar with application permissions even if +you are using native code.

+ + +

Storing Data

+ +

Using internal files

+ +

By default, files created on internal +storage are only accessible to the application that created the file. This +protection is implemented by Android and is sufficient for most +applications.

+ +

Use of +world writable or world readable files for IPC is discouraged because it does not provide +the ability to limit data access to particular applications, nor does it +provide any control on data format. As an alternative, you might consider using +a ContentProvider which provides read and write permissions, and can make +dynamic permission grants on a case-by-case basis.

+ +

To provide additional protection for sensitive data, some applications +choose to encrypt local files using a key that is not accessible to the +application. (For example, a key can be placed in a KeyStore and +protected with a user password that is not stored on the device). While this +does not protect data from a root compromise that can monitor the user +inputting the password, it can provide protection for a lost device without file system +encryption.

+ +

Using external storage

+ +

Files created on external +storage, such as SD Cards, are globally readable and writable. Since +external storage can be removed by the user and also modified by any +application, applications should not store sensitive information using +external storage.

+ +

As with data from any untrusted source, applications should perform input +validation when handling data from external storage (see Input Validation +section). We strongly recommend that applications not store executables or +class files on external storage prior to dynamic loading. If an application +does retrieve executable files from external storage they should be signed and +cryptographically verified prior to dynamic loading.

+ +

Using content providers

+ +

ContentProviders provide a structured storage mechanism that can be limited +to your own application, or exported to allow access by other applications. By +default, a + +ContentProvider is +exported + for use by other applications. If you do not intend to provide other +applications with access to your + +ContentProvider, mark them as +android:exported=false in the application manifest.

+ +

When creating a +ContentProvider + that will be exported for use by other applications, you can specify +a single +permission + for reading and writing, or distinct permissions for reading and writing +within the manifest. We recommend that you limit your permissions to those +required to accomplish the task at hand. Keep in mind that it’s usually +easier to add permissions later to expose new functionality than it is to take +them away and break existing users.

+ +

If you are using a + +ContentProvider for sharing data between applications built by the +same developer, it is preferable to use +signature +level permissions. Signature permissions do not require user confirmation, +so they provide a better user experience and more controlled access to the + + +ContentProvider.

+ +

ContentProviders can also provide more granular access by declaring the +grantUriPermissions element and using the FLAG_GRANT_READ_URI_PERMISSION and FLAG_GRANT_WRITE_URI_PERMISSION flags in the Intent object +that activates the component. The scope of these permissions can be further +limited by the +grant-uri-permission element.

+ +

When accessing a + +ContentProvider, use parameterized query methods such as +query(), update(), and delete() to avoid +potential SQL +Injection from untrusted data. Note that using parameterized methods is not +sufficient if the selection is built by concatenating user data +prior to submitting it to the method.

+ +

Do not have a false sense of security about the write permission. Consider +that the write permission allows SQL statements which make it possible for some +data to be confirmed using creative WHERE clauses and parsing the +results. For example, an attacker might probe for presence of a specific phone +number in a call-log by modifying a row only if that phone number already +exists. If the content provider data has predictable structure, the write +permission may be equivalent to providing both reading and writing.

+ + +

Using Interprocess Communication (IPC)

+ +

Some Android applications attempt to implement IPC using traditional Linux +techniques such as network sockets and shared files. We strongly encourage the +use of Android system functionality for IPC such as Intents, Binders, Services, +and Receivers. The Android IPC mechanisms allow you to verify the identity of +the application connecting to your IPC and set security policy for each IPC +mechanism.

+ +

Many of the security elements are shared across IPC mechanisms. +Broadcast Receivers, +Activities, and +Services are all declared in the application manifest. If your IPC mechanism is +not intended for use by other applications, set the android:exported property +to false. This is useful for applications that consist of multiple processes +within the same UID, or if you decide late in development that you do not +actually want to expose functionality as IPC but you don’t want to rewrite +the code.

+ +

If your IPC is intended to be accessible to other applications, you can +apply a security policy by using the +Permission tag. If IPC is between applications built by the same developer, +it is preferable to use signature +level permissions. Signature permissions do not require user confirmation, +so they provide a better user experience and more controlled access to the IPC +mechanism.

+ +

One area that can introduce confusion is the use of intent filters. Note +that Intent filters should not be considered a security feature -- components +can be invoked directly and may not have data that would conform to the intent +filter. You should perform input validation within your intent receiver to +confirm that it is properly formatted for the invoked receiver, service, or +activity.

+ +

Using intents

+ +

Intents are the preferred mechanism for asynchronous IPC in Android. +Depending on your application requirements, you might use sendBroadcast(), sendOrderedBroadcast(), or +direct an intent to a specific application component.

+ +

Note that ordered broadcasts can be “consumed” by a recipient, so they +may not be delivered to all applications. If you are sending an Intent where +delivery to a specific receiver is required, the intent must be delivered +directly to the receiver.

+ +

Senders of an intent can verify that the recipient has a permission +specifying a non-Null Permission upon sending. Only applications with that +Permission will receive the intent. If data within a broadcast intent may be +sensitive, you should consider applying a permission to make sure that +malicious applications cannot register to receive those messages without +appropriate permissions. In those circumstances, you may also consider +invoking the receiver directly, rather than raising a broadcast.

+ +

Using binder and AIDL interfaces

+ +

Binders are the +preferred mechanism for RPC-style IPC in Android. They provide a well-defined +interface that enables mutual authentication of the endpoints, if required.

+ +

We strongly encourage designing interfaces in a manner that does not require +interface specific permission checks. Binders are not declared within the +application manifest, and therefore you cannot apply declarative permissions +directly to a Binder. Binders generally inherit permissions declared in the +application manifest for the Service or Activity within which they are +implemented. If you are creating an interface that requires authentication +and/or access controls on a specific binder interface, those controls must be +explicitly added as code in the interface.

+ +

If providing an interface that does require access controls, use checkCallingPermission() to verify whether the +caller of the Binder has a required permission. This is especially important +before accessing a Service on behalf of the caller, as the identify of your +application is passed to other interfaces. If invoking an interface provided +by a Service, the bindService() + invocation may fail if you do not have permission to access the given Service. + If calling an interface provided locally by your own application, it may be +useful to use the +clearCallingIdentity() to satisfy internal security checks.

+ +

Using broadcast receivers

+ +

Broadcast receivers are used to handle asynchronous requests initiated via +an intent.

+ +

By default, receivers are exported and can be invoked by any other +application. If your +BroadcastReceivers is intended for use by other applications, you +may want to apply security permissions to receivers using the +<receiver> element within the application manifest. This will +prevent applications without appropriate permissions from sending an intent to +the +BroadcastReceivers.

+ +

Using Services

+ +

Services are often used to supply functionality for other applications to +use. Each service class must have a corresponding declaration in its +package's AndroidManifest.xml.

+ +

By default, Services are exported and can be invoked by any other +application. Services can be protected using the android:permission attribute +within the manifest’s +<service> tag. By doing so, other applications will need to declare +a corresponding <uses-permission> element in their own manifest to be +able to start, stop, or bind to the service.

+ +

A Service can protect individual IPC calls into it with permissions, by +calling checkCallingPermission()before executing +the implementation of that call. We generally recommend using the +declarative permissions in the manifest, since those are less prone to +oversight.

+ +

Using Activities

+ +

Activities are most often used for providing the core user-facing +functionality of an application. By default, Activities are exported and +invokable by other applications only if they have an intent filter or binder +declared. In general, we recommend that you specifically declare a Receiver or +Service to handle IPC, since this modular approach reduces the risk of exposing +functionality that is not intended for use by other applications.

+ +

If you do expose an Activity for purposes of IPC, the android:permission attribute in the +<activity> declaration in the application manifest can be used to +restrict access to only those applications which have the stated +permissions.

+ + +

Using Permissions

+ +

Requesting Permissions

+ +

We recommend minimizing the number of permissions requested by an +application. Not having access to sensitive permissions reduces the risk of +inadvertently misusing those permissions, can improve user adoption, and makes +applications less attractive targets for attackers.

+ +

If it is possible to design your application in a way that does not require +a permission, that is preferable. For example, rather than requesting access +to device information to create an identifier, create a GUID for your application. +(This specific example is also discussed in Handling User Data) Or, rather than +using external storage, store data in your application directory.

+ +

If a permission is not required, do not request it. This sounds simple, but +there has been quite a bit of research into the frequency of over-requesting +permissions. If you’re interested in the subject you might start with this +research paper published by U.C. Berkeley: +http://www.eecs.berkeley.edu/Pubs/TechRpts/2011/EECS-2011-48.pdf

+ +

In addition to requesting permissions, your application can use permissions +to protect IPC that is security sensitive and will be exposed to other +applications -- such as a +ContentProvider. In general, we recommend using access controls +other than user confirmed permissions where possible since permissions can +be confusing for users. For example, consider using the signature +protection level on permissions for IPC communication between applications +provided by a single developer.

+ +

Do not cause permission re-delegation. This occurs when an app exposes data +over IPC that is only available because it has a specific permission, but does +not require that permission of any clients of it’s IPC interface. More +details on the potential impacts, and frequency of this type of problem is +provided in this research paper published at USENIX: http://www.cs.be +rkeley.edu/~afelt/felt_usenixsec2011.pdf

+ +

Creating Permissions

+ +

Generally, you should strive to create as few permissions as possible while +satisfying your security requirements. Creating a new permission is relatively +uncommon for most applications, since +system-defined permissions cover many situations. Where appropriate, +perform access checks using existing permissions.

+ +

If you must create a new permission, consider whether you can accomplish +your task with a Signature permission. Signature permissions are transparent +to the user and only allow access by applications signed by the same developer +as application performing the permission check. If you create a Dangerous +permission, then the user needs to decide whether to install the application. +This can be confusing for other developers, as well as for users.

+ +

If you create a Dangerous permission, there are a number of complexities +that you need to consider. +

+ +

Each of these poses a significant non-technical challenge for an application +developer, which is why we discourage the use of Dangerous permission.

+ + +

Using Networking

+ +

Using IP Networking

+ +

Networking on Android is not significantly different from Linux +environments. The key consideration is making sure that appropriate protocols +are used for sensitive data, such as HTTPS for +web traffic. We prefer use of HTTPS over HTTP anywhere that HTTPS is +supported on the server, since mobile devices frequently connect on networks +that are not secured, such as public WiFi hotspots.

+ +

Authenticated, encrypted socket-level communication can be easily +implemented using the SSLSocket +class. Given the frequency with which Android devices connect to unsecured +wireless networks using WiFi, the use of secure networking is strongly +encouraged for all applications.

+ +

We have seen some applications use localhost network ports for +handling sensitive IPC. We discourage this approach since these interfaces are +accessible by other applications on the device. Instead, use an Android IPC +mechanism where authentication is possible such as a Service and Binder. (Even +worse than using loopback is to bind to INADDR_ANY since then your application +may receive requests from anywhere. We’ve seen that, too.)

+ +

Also, one common issue that warrants repeating is to make sure that you do +not trust data downloaded from HTTP or other insecure protocols. This includes +validation of input in WebView and +any responses to intents issued against HTTP.

+ +

Using Telephony Networking

+ +

SMS is the telephony protocol most frequently used by Android developers. +Developers should keep in mind that this protocol was primarily designed for +user-to-user communication and is not well-suited for some application +purposes. Due to the limitations of SMS, we strongly recommend the use of C2DM and IP networking for +sending data messages to devices.

+ +

Many developers do not realize that SMS is not encrypted or strongly +authenticated on the network or on the device. In particular, any SMS receiver +should expect that a malicious user may have sent the SMS to your application +-- do not rely on unauthenticated SMS data to perform sensitive commands. +Also, you should be aware that SMS may be subject to spoofing and/or +interception on the network. On the Android-powered device itself, SMS +messages are transmitted as Broadcast intents, so they may be read or captured +by other applications that have the READ_SMS permission.

+ + +

Dynamically Loading Code

+ +

We strongly discourage loading code from outside of the application APK. +Doing so significantly increases the likelihood of application compromise due +to code injection or code tampering. It also adds complexity around version +management and application testing. Finally, it can make it impossible to +verify the behavior of an application, so it may be prohibited in some +environments.

+ +

If your application does dynamically load code, the most important thing to +keep in mind about dynamically loaded code is that it runs with the same +security permissions as the application APK. The user made a decision to +install your application based on your identity, and they are expecting that +you provide any code run within the application, including code that is +dynamically loaded.

+ +

The major security risk associated with dynamically loading code is that the +code needs to come from a verifiable source. If the modules are included +directly within your APK, then they cannot be modified by other applications. +This is true whether the code is a native library or a class being loaded using + +DexClassLoader. We have seen many instances of applications +attempting to load code from insecure locations, such as downloaded from the +network over unencrypted protocols or from world writable locations such as +external storage. These locations could allow someone on the network to modify +the content in transit, or another application on a users device to modify the +content, respectively.

+ + +

Using WebView

+ +

Since WebView consumes web content that can include HTML and JavaScript, +improper use can introduce common web security issues such as cross-site-scripting (JavaScript injection). Android includes a number of mechanisms to reduce +the scope of these potential issues by limiting the capability of WebView to +the minimum functionality required by your application.

+ +

If your application does not directly use JavaScript within a WebView, do +not call +WebView does +not execute JavaScript so cross-site-scripting is not possible.

+ +

Use addJavaScriptInterface() with +particular care because it allows JavaScript to invoke operations that are +normally reserved for Android applications. Only expose addJavaScriptInterface() to +sources from which all input is trustworthy. If untrusted input is allowed, +untrusted JavaScript may be able to invoke Android methods. In general, we +recommend only exposing addJavaScriptInterface() to +JavaScript that is contained within your application APK.

+ +

Do not trust information downloaded over HTTP, use HTTPS instead. Even if +you are connecting only to a single website that you trust or control, HTTP is +subject to MiTM attacks +and interception of data. Sensitive capabilities using addJavaScriptInterface() should +not ever be exposed to unverified script downloaded over HTTP. Note that even +with the use of HTTPS, +addJavaScriptInterface() +increases the attack surface of your application to include the server +infrastructure and all CAs trusted by the Android-powered device.

+ +

If your application accesses sensitive data with a WebView, you +may want to use the +clearCache() method to delete any files stored locally. Server side +headers like no-cache can also be used to indicate that an application should +not cache particular content.

+ + +

Performing Input Validation

+ +

Insufficient input validation is one of the most common security problems +affecting applications, regardless of what platform they run on. Android does +have platform-level countermeasures that reduce the exposure of applications to +input validation issues, you should use those features where possible. Also +note that selection of type-safe languages tends to reduce the likelihood of +input validation issues. We strongly recommend building your applications with +the Android SDK.

+ +

If you are using native code, then any data read from files, received over +the network, or received from an IPC has the potential to introduce a security +issue. The most common problems are buffer overflows, use after +free, and off-by-one errors. +Android provides a number of technologies like ASLR and DEP that reduce the +exploitability of these errors, but they do not solve the underlying problem. +These can be prevented by careful handling of pointers and managing of +buffers.

+ +

Dynamic, string based languages such as JavaScript and SQL are also subject +to input validation problems due to escape characters and script injection.

+ +

If you are using data within queries that are submitted to SQL Database or a +Content Provider, SQL Injection may be an issue. The best defense is to use +parameterized queries, as is discussed in the ContentProviders section. +Limiting permissions to read-only or write-only can also reduce the potential +for harm related to SQL Injection.

+ +

If you are using WebView, then +you must consider the possibility of XSS. If your application does not +directly use JavaScript within a WebView, do +not call setJavaScriptEnabled() and XSS is no longer possible. If you must +enable JavaScript then the WebView section provides other security best +practices.

+ +

If you cannot use the security features above, we strongly recommend the use +of well-structured data formats and verifying that the data conforms to the +expected format. While blacklisting of characters or character-replacement can +be an effective strategy, these techniques are error-prone in practice and +should be avoided when possible.

+ + +

Handling User Data

+ +

In general, the best approach is to minimize use of APIs that access +sensitive or personal user data. If you have access to data and can avoid +storing or transmitting the information, do not store or transmit the data. +Finally, consider if there is a way that your application logic can be +implemented using a hash or non-reversible form of the data. For example, your +application might use the hash of an an email address as a primary key, to +avoid transmitting or storing the email address. This reduces the chances of +inadvertently exposing data, and it also reduces the chance of attackers +attempting to exploit your application.

+ +

If your application accesses personal information such as passwords or +usernames, keep in mind that some jurisdictions may require you to provide a +privacy policy explaining your use and storage of that data. So following the +security best practice of minimizing access to user data may also simplify +compliance.

+ +

You should also consider whether your application might be inadvertently +exposing personal information to other parties such as third-party components +for advertising or third-party services used by your application. If you don't +know why a component or service requires a personal information, don’t +provide it. In general, reducing the access to personal information by your +application will reduce the potential for problems in this area.

+ +

If access to sensitive data is required, evaluate whether that information +must be transmitted to a server, or whether the operation can be performed on +the client. Consider running any code using sensitive data on the client to +avoid transmitting user data.

+ +

Also, make sure that you do not inadvertently expose user data to other +application on the device through overly permissive IPC, world writable files, +or network sockets. This is a special case of permission redelegation, +discussed in the Requesting Permissions section.

+ +

If a GUID is required, create a large, unique number and store it. Do not +use phone identifiers such as the phone number or IMEI which may be associated +with personal information. This topic is discussed in more detail in the Android Developer Blog.

+ +

Handling Credentials

+ +

In general, we recommend minimizing the frequency of asking for user +credentials -- to make phishing attacks more conspicuous, and less likely to be +successful. Instead use an authorization token and refresh it.

+ +

Where possible, username and password should not be stored on the device. +Instead, perform initial authentication using the username and password +supplied by the user, and then use a short-lived, service-specific +authorization token.

+ +

Services that will be accessible to multiple applications should be accessed +using + +AccountManager. If possible, use the +AccountManager class to invoke a cloud-based service and do not store +passwords on the device.

+ +

After using +AccountManager to retrieve an Account, check the CREATOR + before passing in any credentials, so that you do not inadvertently pass +credentials to the wrong application.

+ +

If credentials are to be used only by applications that you create, then you +can verify the application which accesses the +AccountManager using checkSignature(). +Alternatively, if only one application will use the credential, you might use a +KeyStore for +storage.

+ + +

Using Cryptography

+ +

In addition to providing data isolation, supporting full-filesystem +encryption, and providing secure communications channels Android provides a +wide array of algorithms for protecting data using cryptography.

+ +

In general, try to use the highest level of pre-existing framework +implementation that can support your use case. If you need to securely +retrieve a file from a known location, a simple HTTPS URI may be adequate and +require no knowledge of cryptography on your part. If you need a secure +tunnel, consider using + +HttpsURLConnection or SSLSocket, +rather than writing your own protocol.

+ +

If you do find yourself needing to implement your own protocol, we strongly +recommend that you not implement your own cryptographic algorithms. Use +existing cryptographic algorithms such as those in the implementation of AES or +RSA provided in the Cipher class.

+ +

Use a secure random number generator ( + +SecureRandom) to initialize any cryptographic keys ( +KeyGenerator). Use of a key that is not generated with a secure random +number generator significantly weakens the strength of the algorithm, and may +allow offline attacks.

+ +

If you need to store a key for repeated use, use a mechanism like KeyStore that +provides a mechanism for long term storage and retrieval of cryptographic +keys.

+ +

Conclusion

+ +

Android provides developers with the ability to design applications with a +broad range of security requirements. These best practices will help you make +sure that your application takes advantage of the security benefits provided by +the platform.

+ +

You can receive more information on these topics and discuss security best +practices with other developers in the Android Security +Discuss Google Group

-- cgit v1.2.3