Android security ================ Today's topic is app-vs-app access control. Which apps should be able to use your contacts, location, SMS, &c? Which third-party apps should be able to interact? We will be taking for granted: Isolation of applications. Correctness of kernel and system software. Defense against theft of device. Of course it's simplistic to view these as independent: Errors in one area can undermine other areas (e.g. if weak isolation). Strength in one area can help others (e.g. least priv vs bugs). Android has cool properties with respect to application security. Anyone can write an application (don't need Google's permission). Users can run any apps they like. Secure even if apps are malicious! (Probably.) iOS is similar. But previous consumer systems were not! iPhone/Android explored new ground for consumer application security. Challenge that Android addresses: isolation and sharing. Desktop applications provide easy sharing. + Applications can easily interact with one another, share files. + User can choose app for each task (email app, image viewer, etc). - Every app has user's full privileges. So, big problem if an app is malicious or compromised: e.g., ransomware. - Little notion of app vs app control for same user. - Focus is file access; not much access control for IPC to services. Isolation mechanisms provide little support for sharing. E.g., VMs like in AWS Lambda; WebAssembly. Strong isolation but not a great fit for an end-user device. Sometimes strong isolation gets used on security-critical end-user systems. Put applications into separate VMs. [[ Ref: https://www.qubes-os.org/ ]] But difficult to use in the common case. E.g., handling video files: Downloaded photos/videos into one VM. How to edit them in the photoshop VM? How to upload them to youtube after that? E.g., handling mail attachments: Mail VM wants to view a PDF attachment; how to share with PDF VM? Filled out a PDF form in that VM; how to email it back to someone? We've seen some sharing ideas but nothing that works for an end user. Sharing in OKWS through db proxy. Sharing in RLbox through annotated library API. Web/browser-based applications (will talk more about them later): + No need to install applications or worry about local state. + Browser isolates different web sites; good for security. - Browser isolates different web sites; not much sharing. - Requires a server; hard to use offline. What does an Android application look like? Regular process on Linux. Each application has private file storage. /data/data/appname Manifest declaring its permissions. Entire application is signed by the developer. How does Android isolate apps from each other? Goal: interaction *only* via Android messaging. e.g. no sharing of files. Isolation implemented with Linux kernel facilities. Originally just UNIX UID per application. Now SELinux and seccomp to limit system call privileges. E.g., SELinux protects app files on SD card even when using FAT w/o ACLs. Is pure isolation enough? Need to allow+control access to contacts, phone, SMS, network, &c. And to services from 3rd party apps, as in paper. How do applications interact and share information? Intent: basic messaging primitive in Android. Lets one app access a service provided by another app, like RPC. Note: no inter-app direct file access; all interaction via intents. How do intents connect to applications? Java bindings for sending / receiving intents. Android will start app process if it gets an intent but not running yet. Java bindings expect application to be composed of "components". Four types of components: Activity: UI component of app, typically one activity per "screen". Service: background processing, RPC service. Content provider: a SQL database. Broadcast receiver: gets broadcast announcements from other components. Components show up in the app's manifest. Intent fields: Component: name of target component (just a string). E.g., com.google.someapp/ComponentName Action: the opcode for this message (just a string). E.g., android.intent.action.MAIN, android.intent.action.DIAL, .. Data: URI of data for the action (just a string). E.g., tel:16172536005, content://contacts/people/1 (for DIAL). All intents are routed via a single trusted "reference monitor". Intent can be implicit: no component name specified. Sender doesn't know what app will receive. Reference monitor figures out target based on action. So communication may occur between apps that know nothing of each other. Great for flexibility, substitution of applications. How does the reference monitor decide whether to allow an intent? "Permission labels" denote individual privileges. Each label is a free-form string. Commonly written as Java-style package names, for uniqueness. E.g., com.android.phone.DIALPERM. An application has a set of labels it is authorized to use. E.g., if app can dial the phone, ...DIALPERM is in its label set. Each component has a single label that protects it. Any intents to that component must be sent by app that has that label. E.g., phone dialer service is labeled with ...DIALPERM. For content providers, two labels: one for read, one for write. Example privileges (these are all "dangerous") calendar camera contacts location phone SMS external storage How does an application get permissions? App's manifest lists the set of permission labels it wants. Manifest is written by the developer. Manifest can ask for any permissions (!). Manifest also declares a label to protect each component. Original plan: ask for permissions at install time. Android shows permissions that the application's manifest requests. User can say "yes" or "no". Paper says this didn't work out well: users not equipped (section 4.3.1). Newer plan: confirm permissions when app tries to use them. App cannot change its manifest (w/o re-install, re-ask). Reference monitor knows each installed app's manifest. Three types of Android permission: Normal: Use is unlikely to be a security problem; at most annoying. E.g., change wallpaper, change audio volume, install a shortcut. System doesn't ask the user about "normal" permissions. Why bother at all? User can review if really interested. Least-privilege, if application is compromised later. Dangerous: Could allow an app to do something dangerous. E.g., send SMS, access contact information. System asks user about dangerous permissions. Signature: Can only be used by apps signed by the same developer. E.g., network configuration app is special, other apps can't ask for perm. Why the manifest / reference monitor? Alternative: component deciding at run-time whether to accept each intent? Programmers tend to forget security checks! Manifest + reference monitor make enforcement the default. Helps user understand some security implications of installing an app. Choose app that doesn't ask for extraneous permissions. Helps Google Play (store) analyze applications. This is an example of Mandatory Access Control (MAC). Permissions specified separately from code. MAC schemes show up a lot, have nice properties: Can be analyzed without understanding app code. Provide some security despite sloppy app code. Usually easy to set up "default nothing" policies. Contrast: discretionary access control (DAC) in Unix. Each UNIX app sets its own permissions on files. Permissions can be changed by the app over time. Hard to tell what will happen just by looking at current file perms. Android app components can perform their own checks on incoming intents. Necessary when an application provides an RPC service. Many different RPC functions. Different level of protection for each RPC function. Reference monitor just checks if client can access the entire service. Not quite a pure MAC model: can't just look at manifest. The story so far is relatively simple: Permissions guard access to sensitive components. Usually one-to-one correspondence between permission name and component. Matrix: apps vs components. SMS Camera Tweet App1 X X App2 X X Jargon: The sending app is the "subject". The receiving component is the "object". Permissions protect objects against use by subjects. Permissions can protect privacy of data in components. Permissions do not protect the privacy of sent intents. Android permissions are pretty flexible. Any app can make up a new permission (doesn't require special privs). Apps don't have to know who will use the permissions. Unlike a conventional ACL, which lists specific users. If a user changes to a new compatible contacts manager, apps that use contacts will continue to work. Apps can ask for lots of privileges if they want. But it's transparent -- the user sees and must approve. Is it good to rely on user to decide if permissions are OK? Works well if the app wants nothing dangerous. User can be confident app can't do much bad when run. If app wants dangerous perms: Users are not great at deciding about security risks. User essentially has to decide if developer is trustworthy. That's hard! But a lot better than not asking. "Who decides, and how" has long been a puzzling question. Sadly, the permission system required more complexity to be useful. Problem: how to control distribution of private broadcast intents? E.g., SMS_RECEIVED intent sent for an incoming SMS message. Eavesdropping app can declare "open" broadcast receiver. Since labels defend receivers, not senders. Solution: sender can specify extra permission label for bcast intent. Reference monitor checks that receiving app has the permission. As if sent msg were object, and receiver were subject. So receiver would have to ask user for e.g. RECEIVE_SMS permission. Note: breaks MAC model slightly Looking at manifest isn't enough to reason about security What happens if two apps define the same permission name? First one wins. Malicious app could register some important perm name as "normal". Any app can then get this permission w/o asking user. Other apps may define this perm to be "dangerous". But the "dangerous" is ignored if perm already defined. Aside: why must applications be signed by developer? Allow upgrade only if signed by same developer. Allow signature perms if signed by same developer. How to give another app temporary permissions? URI delegation. E.g. App1 can read content, sends URI to App2 w/ flag saying App2 should be able read URI content too. Reference monitor keeps track of delegations. Must remember to revoke delegated access! E.g., URI may mean another record at a later time.. Pending intents. App1 gives pending intent to App2. App2 can later send, but with App1's permissions! Reference monitor keeps track. Use case: callbacks into your application, for event notification. Intent can be aimed at a private component in App1. Prevents forgery of even notification since other apps can't access. Not a pure MAC model: manifest doesn't have the full security story. Another example of MAC policy: Enterprise security. User can define multiple profiles on the same phone. SELinux policy provides strong isolation between user profiles. Perhaps other policies can also be specified / enforced. Off-device app security mechanisms. Google Play Protect. Server-side auditing / scanning of applications. Device can choose to install apps only from Google Play store. Similar to iOS policy, but not mandatory. How secure is the Android "platform"? Kernel and setuid-root bugs do occur. And they do subvert the access controls. But they are hard/expensive to find. Users install malware with dangerous permissions. Actual common malware: send SMS messages to premium numbers. Attackers directly get money by deploying such malware. Why do users make such mistakes? Some permissions necessary for both mundane + sensitive tasks. E.g. unique device ID same perm as access phone state. Lots of requests for dangerous permissions, de-sensitizes user. Another cause: apps ask for permissions "just in case". Later upgrade might need them. Another cause: cannot say "no" to subset of permissions. Another cause: copies of existing Android apps containing malware. How to fix? Ask user when the permission is actually used for the first time. Actually deployed in Android now; one of the major recent changes. User can install but later say "No" to specific perm use. Allow user to selectively disable certain permissions. Static/runtime analysis and auditing -- implemented by Google now. Looks for near-identical clones of existing popular apps. Runs apps for a little bit to determine what they do. Android's app market (Google Play) can remotely kill an app. How do you know you've installed the right bank application? Maybe a more coherent iPhone-like app store would help. Hard to exploit many phones and avoid detection. Summary: Android has a well-developed notion of app/app access control. More useful than UNIX's user/user access control. Sophisticated fine-grained permissions at the level of intents. Reasonable to download and run unknown apps, unlike on desktop. Relies on user consent, for better or worse. Has been pretty successful. References: https://source.android.com/security/ http://developer.android.com/guide/topics/security/security.html http://research.microsoft.com/pubs/149596/AppFence.pdf http://seasonofcode.com/posts/internal-input-event-handling-in-the-linux-kernel-and-the-android-userspace.html https://dzone.com/articles/depth-android-package-manager https://en.wikipedia.org/wiki/Stagefright_(bug) https://source.android.com/compatibility/cdd