Android security ================ bug in the paper: in Figure 1, in the FriendViewer application, the top right blue oval (shown as Activity "FriendTracker") should actually be a rounded-rectangle Activity "FriendMap" (see Figure 2). what does an android application look like? made up of four types of components: activity: UI component of app, typically one activity per "screen". service: background processing, can be invoked by other components. content provider: a database that can be accessed by other components. broadcast receiver: get broadcast announcements from other components. each app also has private file storage. typically written in Java. runs on a Linux kernel + android "platform" (will get to it shortly). app also has a manifest declaring its permissions (later). entire app is signed by the developer. activity: can draw on the screen, get user input, etc. only one activity is running at a time. helps users reason about security of inputs. if i'm running bank app (activity), no other activity is getting my input. intent: basic messaging primitive in android. component: name of component to route the request to (string). e.g., com.google.someapp/ComponentName. action: the opcode for this message (string). e.g., android.intent.action.MAIN, android.intent.action.DIAL, .. data: URI of data for the action (string). e.g., tel:16172536005, content://contacts/people/1 (for DIAL). category: a filtering mechanism for finding where to send intent. e.g., android.intent.category.BROWSABLE means safe to invoke from browser. (for action android.intent.action.VIEW, which views the URI in data.) implicit intents: no component name, system must figure it out. looks at action, data, category. could also ask the user, if multiple components match. explicit intents: component name specified. rpc to services. service can also define an RPC protocol for clients to use. client "binds" a connection to a service. more efficient than sending intents each time. networking. just as in any other Linux system. app can use sockets directly, or via Java's networking libraries. why do we need a new app model? (or, what's wrong with existing models?) desktop applications: not much isolation between apps. every app has full privileges, any one malicious app can take over. nice: apps can interact with one another easily, user can choose apps for different tasks (e.g., different email app, image viewer). web/browser-based applications: requires a server in the typical model (hard to use offline). limited interactions between applications. interactions that do exist are typically hard-wired to particular URLs. (e.g., links to a contact manager app's URL: user cannot choose new one) somewhat limited functionality for purely client-side applications. getting fixed: camera, location info, local storage, worker threads, .. how does android's app model handle app interaction, users choosing apps? mostly based on intents. if multiple apps could perform an operation, send implicit intent. android framework decides which app gets the intent; could ask user. how does android's app model handle app isolation? each app's processes run under a separate uid in Linux. exception: one developer can stick multiple apps into one uid. each app gets its own java runtime. java interpreter not trusted or even required; kernel enforces isolation. what are per-app uids good for? one app cannot directly manipulate another app's memory, files. each app has private directory (/data/data/appname). stores preferences, sqlite DBs for content providers, cached files, .. what's missing from uid isolation: access control to shared resources. intents: who can send, what intents, to whom? network access. removable sd card. devices (camera, compass, etc). specifying all of this policy. first, mechanism. how does android control access to all of the above? network access gids. special group IDs define what apps can talk to the network. gid AID_NET_BT_ADMIN (3001): can create low-level bluetooth sockets gid AID_NET_BT (3002): can create bluetooth socket gid AID_INET (3003): can create IP socket gid AID_NET_RAW (3004): can create raw socket gid AID_NET_ADMIN (3005): can change network config (ifconfig, ..) requires kernel changes to do this. each app gets these group IDs depending on what it should be able to do. no per-IP-address control of network communication. access to removable sd card. why not use file system permissions? want to use FAT file system on SD card, to allow access on other devices. FAT file system has no notion of file ownership, permissions, etc. kernel treats all files on sdcard as belonging to special sdcard_rw (1015). apps that should have access to sdcard are in this group. no finer-grained isolation within the entire sdcard. devices. device files (/dev/camera, /dev/compass, etc) owned by special groups. apps run with appropriate groups in their group list. intents. all intents are routed via a single trusted "reference monitor". runs in the system_server process. reference monitor performs intent resolution (where to send intent?), for implicit intents (ref: ActivityStack.startActivityMayWait) reference monitor checks permissions, based on intent and who sent it. (ref: ActivityStack.startActivityLocked) routes intent to the appropriate application process (or starts a new one) why not just use intents for everything, instead of special groups? efficiency: want direct access to camera, network, sd card files. sending everything via intents could impose significant overhead. how does the reference monitor decide whether to allow an intent? "labels" assigned to applications and components. a label is a free-form string. commonly written as Java-style package names, for uniqueness. e.g., imagine com.android.phone.DIALPERM an application has a list 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. other permissions (network, devices, sdcard) map to special label strings. e.g., android.permission.INTERNET translates to app running w/ gid 3003. how does an application get permissions? each app comes with a manifest declaring permissions (labels) the app needs. also declares the labels that should protect each of its components. when app is installed, android system asks user if it's ok to install app. provides list of permissions the app is requesting. who defines permissions? apps define permissions themselves (recall: just free-form strings). android system defines perms for built-in resources (camera, network, ..) can list with 'adb shell pm list permissions -g' defining a permission means specifying: - user-visible name of the permission - description of the permission for the user - grouping permission into some categories (costs money, private data, ..) - type of permission: "normal", "dangerous", and "signature" what do the three types of permission mean? normal: mostly-benign permissions that could let an app annoy the user. but nothing too drastic. e.g., SET_WALLPAPER diff $(pm list permissions -g -d) and $(pm list permissions -g) system doesn't bother asking the user about "normal" permissions. why bother having them at all? can review if really interested. least-privilege, if app is compromised later. dangerous: could allow an app to do something dangerous. e.g., internet access, access to contact information, etc. signature: can only be granted to apps signed by the same developer. think ForceHTTPS: want to prevent user from accidentally giving it away. why do this checking in the reference monitor, rather than in each app? convenience, so programmers don't forget? could do it in a library on the application side.. intent might be routed to different components based on permissions. don't want to send an intent to component A, which will reject it, if another component B is willing to accept it. mandatory access control (MAC): permissions specified separately from code. want to understand security properties of system without looking at code. contrast: discretionary access control (DAC) in Unix. each 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. turns out apps can perform their own checks (ref: checkCallingPermission()) breaks the MAC model a bit: can't just look at manifest. necessary because one service may export different RPC functions, want different level of protection for each. reference monitor just checks if client can access the entire service. who can register to receive intents? any app can specify it wants to receive intents with arbitrary parameters. e.g., can create activity with an intent filter (in manifest): is this a problem? why or why not? system will prompt user whenever they click on a link to http://web.mit.edu/. only "top-level" user clicks translate to intents, not web page components. might be OK if user is prompted. not so great for broadcast intents, which go to all possible recipients. controlling the distribution of broadcast intents. in paper's example, want FRIEND_NEAR intents to not be disclosed to everyone. solution: sender can specify extra permission label when sending bcast intent. reference monitor only sends this intent to recipients that have that label. how to authenticate the source of intents? generally using a permission label on the receiving component. don't necessarily care who sender is, as long as it had the right perms. turns out apps often forgot to put perm restrictions on broadcast receivers. paper at usenix security 2011: "permission re-delegation attacks". e.g., can create an alarm that beeps and vibrates forever. e.g., can send messages to the settings bcast receiver to toggle wifi, etc. one solution in android: "protected broadcasts" (not complete, but..) reference monitor special-cases some intent actions (e.g., system bootup). only system processes can send those broadcast intents. can a sender rely on names to route intents to a specific component? more broadly, how does android authenticate names? (app names, perm names) no general plan, just first-come-first-served. system names (apps, permissions, etc) win in this model. other apps could be preempted by a malicious app that comes first. could send sensitive data to malicious app, by using app's name. could trust intent from malicious app, by looking at its sender name. could set lax permissions by using a malicious app's perm by name. 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 (including malicious app) can get this permission now. other apps that rely on this perm will be vulnerable to malicious app. even if victim app defines its own perms and is the only one that uses it. (e.g., signature perms.) possibly better: reject installing an app if perm is already defined. allows an app to assume its own perms are correctly defined. still does not allow an app to assume anything about other app/perm names. if app names are not authenticated, why do applications need signatures? representing a developer. no real requirement for a CA. helps Android answer three questions: - did this new version of an app come from the same developer as the old one? (if so, can upgrade.) - did these two apps come from the same developer? (if so, can request same uid.) - did the app come from same developer as the one that defined a permission? (if so, can get access to signature-level perms.) how to give another app temporary permissions? URI delegation. capability-style delegation of URI read/write access. system keeps track of delegated access by literal string URI. e.g., content://gmail/attachment/7 must remember to revoke delegated access! e.g., URI may mean another record at a later time.. (ref: grantUriPermission(), revokeUriPermission()) reference monitor keeps granted URIs in memory. (ref: ActivityManagerService.mGrantedUriPermissions) grants are ephemeral, only last until a reboot. pending intents. use case: callbacks into your application (e.g., from alarm/time service). system_server keeps track of pending intents in memory; ephemeral. (ref: PendingIntentRecord.java) revocation problem, as with URI delegation. breaks the MAC model: can't quite reason about all security from manifest. where are apps stored? two options: internal phone memory or sdcard. internal memory is always controlled by android, so can assume it's safe. installing apps on sdcard is more complicated, but desirable due to space. threat models: worried about malicious app modifying sdcard data. worried about malicious user making copies of a paid app. sdcard uses FAT file system, no file permissions. approach: encrypt/authenticate app code with a per-phone random key. key stored in phone's internal flash, unique to phone. how secure is the android "platform"? platform: kernel + anything running as root. poor track record, historically: many vulnerabilities in kernel, setuid binaries, etc. users quickly find ways to get root access to their locked-down phone. not a huge security problem directly, but adversary could exploit same bugs. some developers even published a "rooting" app in google's app market. app gets to run arbitrary code as root on your phone! how to do better? maybe syscall filtering to make it harder to exploit kernel bugs? not clear. other model for security in mobile phone apps: ios/iphone. prompt for permissions at time of use. users can run app and not give it permissions (unlike android). "normal" permissions not very meaningful in this model. apple approves apps in its app store, in part based on security eval. "reputation-based" system: hard to exploit many phones and avoid detection. apparently android market has similar remote-kill functionality. general ref: http://developer.android.com/guide/topics/security/security.html