Android is a multi-process system in which the application (or part of the system) runs in its own process. The security between the system and the application is enforced at the process level through the Linux facilities (tools, functions), such as assigning the user ID and group ID to the application. A more granular security feature is the "Permission" mechanism to restrict specific actions for a particular process, while "Per-uri permissions" can restrict access to specific data access.
Security Architecture
One of the main ideas in the Android security architecture is that the application is not allowed to perform any actions that adversely affect other applications, systems or users by default. This includes reading or writing the user's private data (such as contact data or email data), reading or writing another application's files, network connections, and keeping the device in a non-sleep state.
The process of an application is a secure sandbox. It cannot interfere with other applications unless the "permissions" is explicitly declared so that it can acquire additional capabilities that the basic sandbox does not have. The permissions that it requests "permissions" can be handled by a variety of actions, such as automatically allowing the permission or by using a user hint or certificate to disallow the permission. Applications require that those "permissions" be statically declared in the program, so they will be known when the program is installed and will not change.
Application Signing
All Android applications (. apk files) must be signed with a certificate, and the private key of the certificate is reserved by the developer. The certificate can be used to identify the author of the application. The certificate also does not require CA signature Authentication (note: CA is a third-party certificate authority, such as VeriSign, etc.). Android applications allow and generally use self-signed certificates (i.e. self-signed certificates). Certificates are used to establish a trust relationship between applications, not to control whether a program can be installed. The most important way a signature affects security is by deciding who can enter the signature-based permisssions, and who can share the user IDs.
user IDs and file access
Each Android application (. apk file) is assigned a unique Linux user ID at the time of installation, which creates a sandbox so that it does not touch other applications (and does not expose other applications to it). This user ID is assigned to it at the time of installation and remains the same value on the device.
Because security restrictions occur at the process level, the code in the two package does not run in the same process, and they will appear as different Linux users. We can use the Shareduserid attribute in the manifest tag in the Androidmanifest.xml file to have the same user ID shared by different package. In this way, the two package is considered to be the same application, with the same user ID (not necessarily) and with the same file access rights. Note: To remain secure, the same user ID is assigned only when two applications are signed with the same signature (and the same shareduserid is requested).
All data stored in the application is given a property-the application's user ID, which makes it inaccessible to other package. When using these methods Getsharedpreferences (string, int), Openfileoutput (string, int), or openorcreatedatabase (string, int, Sqlitedatabase.cursorfactory) to create a new file, you can use mode_world_readable and/or Mode_world_ The writeable flag bit to set whether to allow other package to access read and write this file. When these flag bits are set, the file still belongs to the application, but its global read and/or write permission has been set so that it is visible to any other application.
Using Permissions Permissions
A basic Android program is usually not associated with any permissions, which means that it cannot do anything to disrupt the user or disrupt the data. So in order to use the device-protected features, we have to add one or more <uses-permission> tags in androidmanifest.xml to declare the permissions that your application needs.
Here is an example.
<
manifest
xmlns:android
=
"http://schemas.android.com/apk/res/android"
package
=
"com.android.app.myapp"
>
<
uses-permission
android:name
=
"android.permission.RECEIVE_SMS"
/>
...
</
manifest
>
When an application is installed, the permissions requested by the application is approved for acquisition by the package installer. Package Installer determines whether to grant the program request permission by checking the application's signature and/or the user's exchange results. The user does not check the permissions during use, that is, either approve the permission at the time of installation, make it available by design, or do not approve it so that the user is not able to use the feature at all, and there is no hint that the user will fail.
Many times, a permission failure will cause a SecurityException to be thrown back to the application. But Android doesn't guarantee that this will happen everywhere. For example, when the data is deliver to each receiver, the Sendbroadcast (Intent) method checks permissions, and you will not receive any exception after the method call returns. In almost all cases, a permission failure is printed to log.
The permissions defined by the Android system can be found in the manifest.permission. Any program can define and enforce its own unique permissions, so the permissions defined in Manifest.permission is not a complete list (that is, a permissions that has the ability to customize).
A particular permission may be enforced in many parts of the program's operations:
When the system has a call, to prevent the program to perform other functions;
When you start an activity, you control who can start your acitivity;
When sending and receiving broadcasts, control who can receive your broadcasts or who can send them to you;
When entering and manipulating a content provider;
When binding or starting a service.
Declaration and use of permissions
In order to implement your own permissions, you must first declare the permissions in the Androidmanifest.xml file. Usually we declare by using one or more <permission> tags.
The following example illustrates an application in which it wants to control who can initiate its activity:
<
manifest
xmlns:android
=
"http://schemas.android.com/apk/res/android"
package
=
"com.me.app.myapp"
>
<
permission
android:name
=
"com.me.app.myapp.permission.DEADLY_ACTIVITY"
android:label
=
"@string/permlab_deadlyActivity"
android:description
=
"@string/permdesc_deadlyActivity"
android:permissionGroup
=
"android.permission-group.COST_MONEY"
android:protectionLevel
=
"dangerous"
/>
...
</
manifest
>
Here the <protectionLevel> attribute is required to be declared (usually the system-owned permission will have its corresponding protection level, and our own defined permission generally need to be defined Protecdtion level, if not defined, the default is normal). By declaring this property, we can tell the system how to advertise the user and what to advertise, or tell the system who can own the permission. Please refer to the linked documentation for details.
This I say two more, ah, this protectionlevel sub-four levels, respectively, is normal, dangerous, Signature, Signatureorsystem, the higher the security level.
This <permissionGroup> property is optional and is only used to help the system display permissions to the user (actually tells the system which permission belongs to which permission group). You will typically choose to use the standard system group to set this property, or use your own defined group (more rarely). It is often more appropriate to use a group that already exists, because the UI is easier to display.
It is important to note that both the label and the description need to be provided for permission. These are string resources that can be displayed to the user when the user goes to the permission list (Android:label) or some permission details (android:description). Label should be as short as possible, and need to inform the user that the permission is protecting what functionality is on the line. And description can be used to describe what the program that gets the permission can do, and actually let the user know what the program can do if they agree to the program to get that permission. We usually use two sentences to describe permission, the first to describe the permission, and the second to warn the user of any bad things that might happen if the permission is approved. Here is an example of a label and description describing Call_phone permission:
<
string
name
=
"permlab_callPhone"
>directly call phone numbers</
string
>
<
string
name
=
"permdesc_callPhone"
>Allows the application to call phone numbers without
your intervention. Malicious applications may cause unexpected calls on
your phone bill. Note that this does not allow the application to call
emergency numbers.</
string
>
You can view the existing permissions of the system through the shell command adb shell PM list permissions. In particular, the "-S" option displays these permissions in a format that the user will see.
force the use of permissions in Androidmanifest.xml
The AP's Androidmanifest.xml file allows you to set access rights for each component in the AP, including activity,
Service,broadcastreceiver,contentprovider. These components contain the Android:permission property, which allows you to control access to the component.
Activity permissions permissions restrict who can initiate the activity accordingly. Permission will be checked at context.startactivity () and Activity.startactivityforresult (), if caller does not have the required permissions, A SecurityException is thrown.
Service permissions is used to restrict who can start or bind the service. Permission checks are performed when Context.startservice (), Context.stopservice (), and Context.bindservice () are called. If the caller does not have the required permissions, a SecurityException is thrown.
Broadcastreceiver permissions is used to restrict who can send broadcasts to this receiver. The permission check occurs when the Context.sendbroadcast () is returned and the system sends the broadcast that has been submitted to the appropriate receiver. Eventually, a permission failure will not return to caller a exception; it just won't deliver the intent. Similarly, context.registerreceiver () can have its own permission to restrict who can send broadcasts to a receiver registered in the program. Alternatively, a permission can be provided to Context.sendbroadcast () to restrict which Broadcastreceiver can receive the broadcast.
ContentProvider permission is used to restrict who can access the data provided by ContentProvider. (Content providers a set of additional security mechanisms called URI permissions, which are discussed later) differs from other components, where there are two different permission properties you can setup: Android: Readpermission is used to restrict who can read data in provider, and android:writepermission is used to restrict who can write data to provider. It is important to note that if provider is protected by Read permission and Write permission, then only write permission does not mean that you can read the data in provider. When you get provider for the first time, you need to check the permissions (if you don't have any permission, you'll throw SecurityException). Read permissions are required when using contentresolver.query (), and when using Contentresolver.insert (), Contentresolver.update (), Contentresolver.delete ( ) requires write permissions. In all these cases, no required permission will cause SecurityException to be thrown.
force the use of permissions when sending broadcasts
In addition to the previously mentioned permission (to restrict who can send the broadcast to the corresponding broadcastreceiver), you can also specify a permission when sending the broadcast. Using a permission string when calling Context.sendbroadcast (), you can request that receiver's host program must have a corresponding permission. It is important to note that both receiver and broadcaster can request permission. When this happens, both permission checks need to be passed before the corresponding intent are sent to the relevant destination.
other ways to enforce the use of permissions
You can set any of the fine-grained permissions in the process of invoking the service (I understand more granular permissions here). This is done through the Context.checkcallingpermission (String) method. The call uses a desired permission string, and when the permission is granted, it can be returned to the caller an integer (an integer is returned without being approved). It is important to note that this situation can only occur in calls from another process, typically a service-published IDL interface, or other processes that are provided to others.
Android offers a number of other ways to check permissions. If you have the PID of another process, you can go through the Context method Context.checkpermission (String, int, int) to check the permission for that PID. If you have a package name for another application, you can use Packagemanager method Packagemanager.checkpermission (String, string) directly To determine if the package already has the appropriate permissions.
URI Permissions
The standard permission system we have discussed so far is not enough for content provider. A content provider may want to protect its read and write permissions, while the immediate client corresponding to it also needs to pass a specific URI to other applications so that the URI can be manipulated by other applications. A typical example is a mail program that handles messages with attachments. Access to messages requires the use of permission to protect them, as these are sensitive user data. However, if there is a URI to the picture attachment that needs to be passed to the picture browser, the image browser will not have access to the attachment because he cannot have access to all the messages.
The solution to this problem is Per-uri permission: when initiating an activity or returning a result to an activity, the caller can set the intent.flag_grant_read_uri_permission and /or Intent.flag_grant_write_uri_permission. This causes the activity that receives the intent to gain access to the URI specified by the intent, regardless of whether it has permission to enter the intent corresponding content provider.
This mechanism allows a common Capability-style model, which is driven by user interaction (such as opening an attachment, selecting a contact from a list), and specifically obtaining finer-grained permissions. This is an important way to reduce unnecessary permissions, and this is primarily about permissions that are directly related to the behavior of the program.
The acquisition of these URI permission requires a mate of the content provider (which contains those URIs). It is highly recommended to provide this capability in content provider and to declare support through android:granturipermissions or <grant-uri-permissions> tags.
For more information, refer to Context.granturipermission (), Context.revokeuripermission (), and Context.checkuripermission () methods.
Security and access control in Android