Original address: http://android.xsoftlab.net/training/articles/security-tips.html
The security policies built into the Android system can effectively reduce the security problems of the application. So the application created by default already contains a certain level of security protection.
The security policies that Android contains are:
- Application sandbox, which isolates the app's data, code, and other apps from each other.
- Application frameworks are powerful implementations of common safeguards, such as passwords, permissions, and secure IPC mechanisms.
- Some security technology applications, such as ASLR, NX, ProPolice, Safe_iop, OpenBSD Dlmalloc, OpenBSD calloc, and Linux mmap_min_addr, can reduce the risk of common memory management errors.
- The file encryption system ensures that the data is not stolen after the device is lost.
- User rights grants can restrict access to system features and user data.
- Android-defined permissions can control the program's data only within the scope of the procedure.
The Android security policy mentioned in this article is very important for daily development and should form a good coding habit. Using the following strategies in everyday coding behavior can effectively reduce the risk of unintentional security.
Data storage
The common security problem with applications is whether their data can be accessed by other applications. Android has 3 basic ways of storing data.
Internal storage
By default, files created by the app itself can only be accessed by the app itself. This protection is implemented by the Android framework and is sufficient to handle the security of most applications.
In general, you should avoid using mode_world_writeable or mode_world_readable mode for IPC files, because these modes do not provide the ability to restrict access to data and do not have any control over the data format. If you need to share data between processes, you should consider using ContentProvider. ContentProvider provides data read and write access to the app, and can dynamically grant permissions according to the actual situation.
If you need additional protection for some of the more sensitive data, you can use a key to encrypt the local file. For example, you can put the key in KeyStore and protect it with the user's password. However, this solution is not all-powerful: some hack can monitor the password entered by the user, but this way can protect the lost device.
External storage
Files created on external storage can be read and written globally. Because external memory can be removed by the user or modified by any application, sensitive user data should not be stored on external storage.
Because of the possible existence of an unreliable resource, input validation should be performed when reading data from external memory. We strongly recommend that you do not store executable files or class files for dynamic loading on external storage. If the app needs to receive executables from external storage, the files should be signed, and they should be verified before they are loaded.
Content providers
ContentProvider provides a structured storage mechanism that can form a constraint on all applications. If you do not intend to allow other applications to access your contentprovider, then simply mark the ContentProvider property Android:exported=false in the program's manifest file. Otherwise, setting android:exported=true means that other applications can access the data in it.
By default, when creating ContentProvider, you allow other applications to access the data, and you can restrict reading or writing to a single permission, or you can manage it at the same time.
If you use ContentProvider just to share data between your apps, it's more reasonable to set the Android:protectionlevel property value to "signature". Signature permissions do not require user confirmation, so this can provide a good user experience and more control.
ContentProvider can also provide finer-grained access through the Android:granturipermissions property. Visitors should use the Flag_grant_read_uri_permission flag or the FLAG_GRANT_WRITE_URI_PERMISSION flag in intent to access it. The scope of these permissions can be further limited.
When accessing ContentProvider, use parameterized methods such as query (), update (), and delete () to avoid the SQL injection of the non-trusted sources.
Do not have a false awareness of the security of write permissions. Consider that write permissions allow SQL statements to be executed, which may cause some data to be acknowledged. For example, an attacker could find a specified phone number in the call log, and if the data exists, the attacker would need to modify it to know the result. If the data structure of the contentprovider can be guessed, then the Write permission is equivalent to providing Read permission at the same time.
Use permissions
Because Android each app is in the sandbox, the app must explicitly declare its own permissions if it needs to share resources and data.
Request permission
The fewer permissions we need to recommend an application, the better. This can reduce the risk of abuse of permissions, but also easier for users to accept, but also to reduce the hacker's attack portal. Typically, if a permission is not necessary, do not request it.
This is perfect if the application can do without any permissions. For example, if you need to create a unique identifier by accessing the device information, we recommend a GUID. Also, for example, we recommend internal memory compared to storing data in external memory.
In addition, when requesting permission, you can use < permissions> to protect the IPC. The IPC is particularly sensitive, weak, and exposed to other applications, such as ContentProvider, for security. In addition to the permissions that may be required by the user to confirm, we recommend that you use Access control, because these permissions can confuse users. For example, you might consider using the IPC privilege protection level of "signature" for individual developer applications.
Do not disclose protected permission data. This situation only occurs when the data is shared through the IPC: because it has special permissions, and the client for any IPC interface is not required to present the permission.
More details on the potential impacts, and frequency of this type of problem are provided in this paper published At Usenix:http://www.cs.berkeley.edu/~afelt/felt_usenixsec2011.pdf
Create permissions
Typically, you should use as few permissions as possible, and less privilege means more security. Create permissions This kind of thing is not available to most applications because the system-defined permissions are sufficient to cover all situations, and these permissions provide access checks.
If you must create permissions, consider whether you can use the "signature" protection level to complete your desired tasks. "Signature" will completely expose itself to the user, allowing only applications with the same signature to access it.
If you want to create a "dangerous" level of protection, then something needs to be considered inside:
- Permissions must provide a short string that describes the security of the permission.
- The string describing permissions must be available in different locales.
- If the description of the permission is ambiguous or the user believes that it poses a risk, the user may choose not to install the app.
- If the generator for permissions is not installed, the application may request permissions.
Each of these is an important non-technical challenge for you as a programmer, which may confuse users, which is why we discourage the use of the "dangerous" permission level.
Network security
The network transport itself has a security risk because it includes the user's privacy data. People are increasingly concerned about the privacy of mobile devices, especially when performing network transmissions, so apps need to end up with the best security solutions to protect users ' data security.
Using an IP network
The network environment in which Android is located differs greatly from other Linux systems. The main consideration is to choose the protocol suitable for sensitive data transmission. For example, Httpsurlconnection is used for secure web communication. We recommend that you support HTTPS because mobile devices are frequently connected to non-trusted networks, such as public Wi-Fi hotspots.
Authenticated, socket-level encrypted communication can be easily implemented using the Sslsocket class. Since Android devices are frequently connected to unsecured wireless networks, we strongly recommend that you use a secure network implementation for all applications.
We've also seen some applications that use the localhost network port on sensitive IPC processing. We discourage the use of this approach, because these interfaces can be accessed by other applications and should use the Android IPC mechanism.
Another common problem is that the root certificate is repeatedly used to authenticate non-trusted data downloaded from HTTP or other networks. This also includes input validation for WebView and HTTP request responses.
Using the telephone network
SMS (Short Message Service) protocol is mainly used for personal communication between individuals, it does not apply to the data transmission of the app. Due to SMS limitations, we strongly recommend using Google Cloud Messaging (GCM) and IP networks to transfer data between servers and devices.
Note that SMS does not encrypt the network and devices and does not validate them. In particular, any SMS receiver should consider that a malicious user will send SMS to your app, do not trust SMS data that has not been validated, and use them to perform some sensitive operations. Also, you should be aware that SMS may be intercepted and tampered with on the web. Within an Android device, SMS messages are transmitted by broadcast intent, so the data can be read by applications that have read_sms permissions.
Input validation
No matter which platform the program runs on, not performing sufficient input validation is one of the main reasons for the security of the program. Android provides a platform-level security policy that reduces the exposure to application input validation issues, and applications should use these platform features as much as possible. It should also be noted that the choice of security language tends to reduce the likelihood of input validation problems.
If you are using local code, the data read from the file, the data received from the network, or the data received from the IPC can cause security issues. The most common problems are buffer overflows, the use of freed objects, and so on. Android provides a number of relevant technical tools such as ASLR (Address Space Layout randomization), DEP (Data Execution Prevention), which can reduce the frequency of these errors, But they will not solve the underlying problem. You can carefully handle pointers or manage buffers to prevent these problems from appearing.
SQL injection can be a problem if you use SQL database or ContentProvider for data queries. It is best to avoid these problems by using parameterized query methods. Lowering the permissions to read-only or write-only reduces the risk associated with SQL injection.
If you are not able to use the security recommendations mentioned above, we strongly recommend using well-structured data formats and validating these data formats when used.
Process user Data
In general, the best way to secure a user's data is to use as few APIs as possible to access sensitive data or user data. If you can avoid storing or transmitting this information, do not transfer the data. Consider whether an application can implement a logic that uses a hash code of data or an irreversible form of data. For example, a program might implement the logic of using the hash code of an e-mail address as a key value, which avoids the use of an existing e-mail address, which reduces the chance of exposing the data, and also reduces the chance for an attacker to invade the application.
If the program requires access to the user's personal information, such as a password or user name, remember that some components may require you to provide a privacy policy that explains the use and storage of the data. So the next data access practice simplifies adherence to rules.
You should also consider whether an application inadvertently exposes a user's personal data to a third party. If you are not sure why these third-party components or services use user information, do not provide them. Generally reducing access to personal information can reduce the security risk of this piece.
If you have to access sensitive data, evaluate whether it is necessary to transfer the information to the server, or whether these operations can be performed only on the client. Consider that any code involving user-sensitive data is executed on the client side, which avoids unnecessary network transmission and security leaks.
Also, make sure that user data is not exposed to other applications through IPC, global writable files, or a network socket.
If you need a GUID, you can create a large, unique data to save it. Do not use phone-related numbers, such as phone numbers, IMEI, which may be related to user information.
Be careful when writing to the device log. In Android, the log is a shared resource that can be read by an app with Read_logs permissions. Although the log data is temporary, inappropriate user information logs may inadvertently leak information to other applications.
Use of WebView
Because WebView parses web content such as HTML and JavaScript, improper use can present a common security risk. Android provides a number of mechanisms to shrink the scope of these potential problems, such as by limiting the ability of webview to achieve the minimum operational requirements.
If the program does not use JavaScript directly in WebView, do not call setjavascriptenabled (). Some sample code might use this method, so if you don't need it, close it in your program. By default, WebView does not execute JavaScript, so there is no cross-site scripting attack.
Using Addjavascriptinterface () requires special care because it allows JavaScript to invoke methods reserved for Android native apps. If you use it, make sure that all of the Web content is trustworthy. If untrusted content is allowed to enter, then untrusted JavaScript may invoke the relevant method within the app. In general, we recommend that you use Addjavascriptinterface () when you include JavaScript code within the APK.
If your program accesses sensitive data through WebView, you may need to use the ClearCache () method to delete all files stored locally. We can use certain properties of the HTTP header, such as No-cache, to indicate that the application should not cache certain special content.
Previous versions of Android 4.4 WebKit contain a number of security issues. If the app is running on these versions, you should confirm that the content rendered by WebView is trustworthy. If your app must render open Web content, consider implementing a unique renderer that updates the relevant security patches in a timely manner.
Manage certificates
Generally speaking, we do not recommend frequent requests for user credentials, and we recommend the use of Authorization tokens.
User names and passwords should not usually be local. The user name and password entered by the user should be used to initialize the authentication and then communicate using a permission token.
If an account needs to be accessed by multiple programs, then Accountmanager should be used. If possible, use Accountmanager to interact with the service and never have the password present on the device.
If the certificate is used only as an application that you create, you can use the Checksignature () method for program Access validation. If only one program uses the certificate, then KeyStore may be better for you.
Use password
In addition to protection methods such as data isolation, file system encryption, and secure communication channels, Android provides a range of security measures that are encrypted through algorithms.
Typically, the highest-level security implementations built into Android can already support a variety of security situations. If you need to accept a file from a known location, then the HTTPS URI is sufficient. If you need a secure channel, consider using Httpsurlconnection or sslsocket.
If you find that you do need to implement your own security protocols, you do not recommend implementing your own encryption algorithms. Instead, you should use existing cryptographic algorithms such as the AES encryption algorithm or RSA encryption algorithm provided in cipher.
Use the secure random number generator SecureRandom to initialize the key keygenerator. If the key generated by SecureRandom is not used, the robustness of the cryptographic algorithm is greatly weakened, and it is more susceptible to offline attacks.
If you need to have the key locally for later use, you can use a keystore-like encryption mechanism.
Using interprocess communication
Some apps try to implement IPC using traditional Linux technologies such as network sockets and shared files. We recommend using Android for IPC-enabled system functions such as Intent,binder,messenger and Broadcastreceiver. The IPC mechanism of Android allows you to verify the identity of programs connected to your IPC, and you can set security policies for each IPC mechanism.
Many security elements are shared through the IPC mechanism. If the purpose of your IPC mechanism is not to be used by other applications, set the Android:exported property of the corresponding element to false. This is useful for applications that consist of multiple processes with the same UID, or it can be helpful to turn on the feature later.
If the purpose of the IPC is to be accessible to other applications, you can specify the security policy by using the < permission> element. If the IPC is only intended to be used in two own applications that hold the same key, then android:protectionlevel= "signature" is more appropriate.
Using intent
Intent is the preferred mechanism for asynchronous IPC. Depending on the requirements of the program, you may use Sendbroadcast (), Sendorderedbroadcast (), or explicit intent to specify the application components.
Note that because ordered broadcasts can be consumed by the receiver, these broadcasts may not be distributed to all applications. If you send a broadcast that must be received by the specified receiver, you must use an explicit intent, and the intent should also indicate the name of the broadcast receiver.
The party sending the intent can verify that the receiver is allowing non-null permission method calls. Only apps that have this permission will receive the INETNT. If the intent data in the broadcast is sensitive, you should consider that the permissions used here are not blocked by illegal applications. In this case, you should consider calling the receiver directly instead of using the broadcast.
**note:**intent filters should not be considered as a security feature: Because the component may be tuned by an explicit Intent. You should perform input validation where you receive intent to verify that the intent is formatted to be appropriate for calling the broadcast receiver, service, or activity format.
Using the service
Service is often used as a function to support other programs. Each service must have a corresponding declaration in its manifest file.
By default, the service is not open and cannot be tuned by other applications. However, if Intentfilter is added to the service's declaration, it will be exposed by default. The best way to do this is to explicitly declare the Android:exported property as the property you want. The service can also be protected by the Android:permission property. If this is done, then other programs need to declare the corresponding permissions in their manifest file to start, stop, or bind the service.
The service can also protect IPC calls within its permissions, calling Checkcallingpermission () for necessary checks before executing the implementation of the call. We usually recommend using the permissions declared in the manifest file because there are many vulnerabilities that are ignored.
Using Binder and Messenger interfaces
Binder, Messenger is the primary IPC mechanism for remote procedure calls. They provide a well-defined interface: End-to-end mutual authentication is possible.
We strongly recommend that you design the interface in a way that does not require a specific permission check. Because binder, Messenger is not declared in the app's manifest file, it cannot take specific permissions on it. Their permissions usually come from the permissions declared by the corresponding service or activity. If you create an interface for requesting authentication or accessing the controller, these controllers must be explicitly added to the binder, Messenger interface.
If you create an interface that requires access to the controller, use Checkcallingpermission () to verify that the caller contains the required permissions. This is especially important before accessing the remote proxy for the service, just as your app's identity needs to be passed on to other interfaces. If you call a service-supplied interface, the call to Bindservice () may fail if you do not have the required permissions to access the given service. If you invoke a local interface provided by your app, then clearcallingidentity () can meet the needs of internal security checks.
For more information on performing the IPC related to the service, see bound services.
Using broadcast receivers
The broadcastreceiver is used to process asynchronous requests initiated by intent.
By default, the receiver can be tuned by any app. If your broadcast receiver is used by other programs, you may need to take some security measures on the receiver: Add the appropriate security permissions to the manifest file. This prevents applications that do not have the correct permissions from sending intent to the broadcast receiver.
Dynamic load Code
Dalvik is a runtime virtual machine for Android. Although Dalvik is dedicated to Android, the same security issues on other virtual machines apply to Android as well. There is generally no need to care about the security issues associated with virtual machines, because Android applications run in a secure sandbox environment, so other processes on the system do not have access to program code or private data.
If you are interested in deeper virtual machine security issues, then it is recommended to familiarize yourself with some of the existing literature on this subject. The two most popular resources are as follows:
-Http://www.securingjava.com/toc.html
-Https://www.owasp.org/index.php/Java_Security_Resources
This document focuses on the special feature of Android and how it differs from other virtual machine environments. For developers who are very experienced with other virtual machines, there are two major Android differences:
- Some virtual machines, such as the JVM or the. NET runtime, play the role of a security boundary, isolating code and functionality from the underlying operating system. However, Dalvik virtual machines in Android do not have such functionality-the application sandbox implementation and the operating system level, so Dalvik can interact with the native code of the app without any security restrictions.
- Due to the limited storage space of mobile devices, some developers may need to build applications through modularity and use dynamic loading techniques. If you do, then you need to consider where to receive the application's logic code? Where should the code exist? Do not use code that is not validated, such as code that is loaded from an unsecured network resource or external memory, because the code is likely to be tampered with by other programs.
Security of Local Code
In general, we recommend using the Android SDK for application development, rather than using native code development. Programs built from native code are more complex, lack flexibility, and are more prone to common memory leak errors like buffer overflows.
Because Android is built on Linux kernel, if you use native code, the security issues that you encounter with Linux development also apply to this. Because Linux security is beyond the scope of this article, it provides a welcome resource for "How Linux and Unix can be safely programmed," related address: Http://www.dwheeler.com/secure-programs.
The biggest difference between Android and most other Linux environments is the program sandbox. In Android, all programs run in the program sandbox and include those native code. On the most basic level, for developers who are familiar with Linux, the difference is that each Android application has a unique UID and a small amount of permissions. If you want to use native code development, then you should be very aware of the permissions of the app.
PS: translation of the relevant source files are open source, open Source address: Https://code.csdn.net/u011064099/android-training-chinese-version/tree/master, Welcome to fork, Star.
Android Official Development Document Training Series Course Chinese version: Android security recommendations