Understanding Android Security

来源:互联网 发布:dnf网络交易平台 编辑:程序博客网 时间:2024/05/18 01:23

The nextgeneration of open operating systems won’t be on desktops or mainframes but onthe small mobile devices we carry every day. The openness of these newenvironments will lead to new applications and markets and will enable greaterintegration with existing online services. However, as the importance of thedata and services our cell phones support increases, so too do theopportunities for vulnerability. It’s essential that this next generation ofplatforms provides a comprehensive and usable security infrastructure.

 

Developedby the Open Handset Alliance (visibly led by Google), Android is a widelyanticipated open source operating system for mobile devices that provides abase operating system, an application middleware layer, a Java softwaredevelopment kit (SDK), and a collection of system applications. Although theAndroid SDK has been available since late 2007, the first publicly availableAndroid ready “G1” phone debuted in late October 2008. Since then, Android’sgrowth has been phenomenal: T-Mobile’s G1 manufacturer HTC estimates shipmentvolumes of more than 1 million phones by the end of 2008, and industry insidersexpect public adoption to increase steeply in 2009. Many other cell phoneproviders have either promised or plan to support it in the near future.

 

A largecommunity of developers has organized around Android, and many new products andapplications are now available for it. One of Android’s chief selling points isthat it lets developers seamlessly extend online services to phones. The mostvisible example of this feature is, unsurprisingly, the tight integration ofGoogle’s Gmail, Calendar, and Contacts Web applications with system utilities.Android users simply supply a username and password, and their phonesautomatically synchronize with Google services. Other vendors are rapidlyadapting their existing instant messaging, social networks, and gaming servicesto Android, and many enterprises are

lookingfor ways to integrate their own internal operations (such as inventorymanagement, purchasing, receiving, and so forth) into it as well.

 

Traditionaldesktop and server operating systems have struggled to securely integrate suchpersonal and business applications and services on a single platform. Althoughdoing so on a mobile platform such as Android remains nontrivial, manyresearchers hope it provides a clean slate devoid of the complications thatlegacy software can cause.

 Android doesn’t officially supportapplications developed for other platforms: applications execute on top of aJava middleware layer running on an embedded Linux kernel, so developerswishing to port their application to Android must use its custom user interfaceenvironment.

 

Additionally,Android restricts application interaction to its special APIs by running eachapplication as its own user identity. Although this controlled interaction hasseveral beneficial security features, our experiences developing Androidapplications have revealed that designing secure applications isn’t alwaysstraightforward. Android uses a simple permission label assignment model torestrict access to resources and other applications, but for reasons ofnecessity and convenience, its designers have added several potentiallyconfusing refinements as the system has evolved.

 

Thisarticle attempts to unmask the complexity of Android security and note somepossible development pitfalls that occur when defining an application’ssecurity. We conclude by attempting to draw some lessons and identifyopportunities for future enhancements that should aid in clarity andcorrectness.

 

AndroidApplications

TheAndroid application framework forces a structure on developers. It doesn’t havea  main()function or single entry pointfor execution—instead, developers must design applications in terms ofcomponents.

 

ExampleApplication

Wedeveloped a pair of applications to help describe how Android applicationsoperate. Interested readers can download the source code from our Web site(http://siis.cse.psu.

edu/android_sec_tutorial.html).

 

Let’sconsider a location-sensitive social networking application for mobile phonesin which users can discover their friends’ locations. We split thefunctionality into two applications: one for tracking friends and one forviewing them. As Figure 1 shows, the FriendTracker application consists ofcomponents specific to tracking friend locations (for example, via a Webservice), storing geographic coordinates, and sharing those coordinates withother applications. The user then uses the FriendViewer application to retrievethe stored geographic coordinates and view friends on a map.

 

Bothapplications contain multiple components for performing their respective tasks;the components themselves are classified by their  component types. An Android developer choosesfrom predefined component types depending on the component’s purpose (such asinterfacing with a user or storing data).

 

ComponentTypes

Androiddefines four component types:

•      Activity components define anapplication’s user interface. Typically, an application developer defines oneactivity per “screen.”Activities start each other, possibly passing and returning values. Only oneactivity on the system has keyboard and processing focus at a time; all othersare suspended.

 

•      Service components perform backgroundprocessing. When an activity needs to perform some operation that must continueafter the user interface disappears (such as download a file or play music), itcommonly starts a service specifically designed for that action.

Thedeveloper can also use services as application-specific daemons, possiblystarting on boot. Services often define an interface for Remote Procedure Call(RPC) that other system components can use to send commands and retrieve data,as well as register callbacks.

 

•      Content provider components store andshare data using a relational database interface. Each content provider has anassociated “authority” describing the content it contains. Other components usethe authority name as a handle to perform SQL queries (such as SELECT, INSERT,or DELETE) to read and write content. Although content providers typicallystore values in database records, data retrieval is implementation specific—forexample, files are also shared through content provider interfaces.

 

•      Broadcast receiver components act asmailboxes for messages from other applications. Commonly, application codebroadcasts messages to an implicit destination. Broadcast receivers thussubscribe to such destinations to receive the messages sent to it. Applicationcode can also address a broadcast receiver explicitly by including the namespaceassigned to its containing application.

Figure 1shows the FriendTracker and FriendViewer applications containing the differentcomponent types. The developer specifies components using a manifest file.There are no restrictions on the number of components an application definesfor each type, but as a convention, one component has the same name as theapplication. Frequently, this is an activity, as in the FriendViewerapplication. This activity usually indicates the primary activity that the systemapplication launcher uses to start the user interface; however, the specificactivity chosen on launch is marked by meta information in the manifest.

In theFriendTracker application, for example, the FriendTrackerControl activity ismarked as the

mainuser interface entry point. In this case, we reserved the name “FriendTracker” for the service component performing the coreapplication logic.

 

TheFriendTracker application contains each of the four component types. TheFriendTracker service polls an external service to discover friends’ locations.In our example code, we generate locations randomly, but extending thecomponent to interface with a Web service is straightforward. TheFriendProvider content provider maintains the most recent geographic coordinatesfor friends, the FriendTracker Control activity defines a user interface forstarting and stopping the tracking functionality, and the BootReceiverbroadcast receiver obtains a notification from the system once it boots (theapplication uses this to automatically start the FriendTracker service).

 

TheFriendViewer application is primarily concerned with showing information aboutfriends’ locations. The FriendViewer activity lists all friends and theirgeographic coordinates, and the FriendMap activity displays them on a map. TheFriendReceiver broadcast receiver waits for messages that indicate the physicalphone is near a particular friend and displays a message to the user upon suchan event. Although we could have placed these components within theFriendTracker application, we created a separate application to demonstratecross-application communication. Additionally, by separating the tracking anduser interface logic, we can create alternative user interfaces with differentdisplays and features—that is, many applications can reuse the logic performedin FriendTracker.

 

ComponentInteraction

Theprimary mechanism for component interaction is an intent, which is simply amessage object containing a destination component address and data. The AndroidAPI defines methods that accept intents and uses that information to startactivities (s t a r t A c t i v i t y ( I n t e n t )), start services(startService(Intent)), and (sendBroadcast(Intent)). The invocation of these methods tells theAndroid framework to begin executing code in the target application. Thisprocess of intercomponent communication is known as an action. Simply put, anintent object defines the “intent” to perform an “action.”

 

One ofAndroid’s most powerful features is the flexibility allowed by its intent-addressingmechanism. Although developers can uniquely address atarget component using its application’s namespace, they can alsospecify an implicit name. In the latter case, the system determines the bestcomponent for an action by considering the set of installed applications anduser choices. The implicit name is called an action string because it specifiesthe type of requested action—for example, if the “VIEW” action string isspecified in an intent with data fields pointing to an image file, the systemwill direct the intent to the preferred image viewer. Developers also useaction strings to broadcast a message to a group of broadcast receivers. On thereceiving end, developers use an intent filter to subscribe to specific actionstrings. Android includes additional destination resolution rules, but actionstrings with optional data types are the most common.

 

Figure 2shows the interaction between components in the FriendTracker and FriendViewerapplications and with components in applications defined as part of the baseAndroid distribution. In each case, one component initiates communication withanother. For simplicity, we call this inter component communication (ICC). Inmany ways, ICC is analogous to inter-process communication (IPC) in Unix-basedsystems. To the developer, ICC functions identically regardless of whether thetarget is in the same or a different application, with the exception of thesecurity rules.

 

Theavailable ICC actions depend on the target component. Each component typesupports interaction specific to its type—for example, when FriendViewer startsFriendMap, the FriendMap activity appears on the screen. Service componentssupport start, stop, and bind actions, so the FriendTrackerControlactivity, for instance, can start and stop the FriendTracker servicethat runs in the background. The bind action establishes a connection betweencomponents, allowing the initiator to execute RPCs defined by the service. Inour example, FriendTracker binds to the location manager in the system server.Once bound, FriendTracker invokes methods to register a callback that providesupdates on the phone’s location. Note that if a service is currently bound, anexplicit “stop” action won’t terminate the service until all bound connectionsare released.

 

Broadcastreceiver and content provider components have unique forms of interaction. ICCtargeted at a broadcast receiver occurs as an intent sent (broadcast) eitherexplicitly to the component or, more commonly, to an action string thecomponent subscribes to. For example, FriendReceiver subscribes to thedeveloper-defined “FRIEND_NEAR”action string. FriendTracker broadcasts an intent to this action string when itdetermines that the phone is near a friend; the system then startsFriendReceiver and displays a message to the user.

 

Contentproviders don’t use intents—rather, they’re addressed via an authority stringembedded in a special content URI of the form c o n t e n t : / / < a u t ho r i t y > /<table>/[<id>]. H e r e , <table>indicates atable in the content provider, and <id> optionally specifies a record inthat table. Components use this URI to perform a SQL query on a contentprovider, optionally including WHERE conditions via the query API.

 

SecurityEnforcement

AsFigure 3 shows, Android protects applications and data through a combination oftwo enforcement mechanisms, one at the system level and the other at the ICClevel. ICC mediation defines the core security framework and is this article’sfocus, but it builds on the guarantees provided by the underlying Linux system.

 

In thegeneral case, each application runs as a unique user identity, which letsAndroid limit the potential damage of programming flaws. For example, the Webbrowser vulnerability discovered recently after the official release ofT-Mobile G1 phones only affected the Web browser itself(http://securityevaluators.com/content/case-studies/android/index.jsp). Becauseof this design choice, the exploit couldn’t affect other applications or thesystem. A similar vulnerability in Apple’s iPhone gave way to the first “jailbreaking” technique, which let users replace parts of the underlying system,but would also have enabled a network-based adversary to exploit this flaw(http://securitye valuators . com/content/case-studies/iphone/index.jsp).

 

ICCisn’t limited by user and process boundaries. In fact, all ICC occurs via anI/O control command on a special device node, /dev/binder. Because the file must be world readable and writable forproper operation, the Linux system has no way of mediating ICC. Although userseparation is straightforward and easily understood, controlling ICC is muchmore subtle and warrants careful consideration.

 

As thecentral point of security enforcement, the Android middleware mediates all ICCestablishment by reasoning about labels assigned to applications andcomponents. A reference monitor1 provides mandatory access control(MAC) enforcement of how applications access components. In its simplest form,access to each component is restricted by assigning it an access permissionlabel; this text string need not be unique. Developers assign applicationscollections of permission labels. When a component initiates ICC, the referencemonitor looks at the permission labels assigned to its containing applicationand—if the target component’s access permission label is in thatcollection—allows ICC establishment to proceed. If the label isn’t in thecollection, establishment is denied even if the components are in the sameapplication. Figure 4 depicts this logic.

Thedeveloper assigns permission labels via the XML manifest file that accompaniesevery application package. In doing so, the developer defines the application’ssecurity policy—that is, assigning permission labels to an applicationspecifies its protection domain, whereas assigning permissions to thecomponents in an application specifies an access policy to protect itsresources. Because Android’s policy enforcement is mandatory, as opposed todiscretionary, all permission labels are set at install time and can’t changeuntil the application is reinstalled. However, despite its MAC properties,Android’s permission label model only restricts access to components anddoesn’t currently provide information flow guarantees, such as in domain typeenforcement.

 

SecurityRefinements

Android’s security frameworkis based on the label-oriented ICC mediation described thus far, but ourdescription is incomplete. Partially out of necessity and partially forconvenience, the Google developers who designed Android incorporated severalrefinements to the basic security model, some of which have subtle side effectsand make its overall security difficult to understand.

 

Publicvs. Private Components

Applications often containcomponents that another application should never access—for example, anactivity designed to return a user-entered password could be startedmaliciously. Instead of defining an access permission, the developer could makea component private by either explicitly setting the exported attribute tofalse in the manifest file or letting Android infer if the component should beprivate from other attributes in its manifest definition.

 

Privatecomponents simplify security specification. By making a component private, thedeveloper doesn’t need to worry which permission label to assign it or howanother application might acquire that label. Any application can accesscomponents that aren’t explicitly assigned an access permission, so theaddition of private components and inference rules (introduced in the v0.9r1SDK release, August 2008) significantly reduces the attack surface for manyapplications. However, the developer must be careful when allowing Android todetermine if a component is private. Security-aware developers should alwaysexplicitly define the exported attribute for components intended to be private.

 

ImplicitlyOpen Components

Developersfrequently define intent filters on activities to indicate that they can handlecertain types of action/data combinations. Recall the example of how the systemfinds an image viewer when an intent specifying the VIEW action and an imagereference is passed to the “start activity” API. In this case, the caller can’tknow beforehand (much less at development time) what access permission isrequired. The developer of the target activity can permit such functionality bynot  assigning  an access permission to it—that is, if apublic component doesn’t explicitly have an access permission listed in itsmanifest definition, Android permits any application to access it.

 

Althoughthis default policy specification enables functionality and ease ofdevelopment, it can lead to poor security practices and is contrary to SaltzerandSchroeder’s principle of fail-safe defaults.4Referring back toour example FriendViewer application, if the FriendReceiver broadcast receiverisn’t assigned an access permission, any unprivileged installed application canforge a  FRIEND_NEAR message, whichrepresents a significant security concern for applications making decisionsbased on information passed via the intent. As a general practice,security aware developers should always assign access permissions to publiccomponents—in fact, they should have an explicit reason for not assigning one.All inputs should be scrutinized under these conditions.