Android App Security · Inside an APK · Lesson 2 of 5
The Manifest
Read an app's manifest to see what it asks for and which doors it opens.
Identity and permissions
Every app must include AndroidManifest.xml. Android reads it at install time, and an app can't use a permission or a component it hasn't declared there. That makes the manifest the most honest summary of what an app intends to do.
The first thing it holds is the package name, such as com.example.quicknotes. It's the app's unique ID. Only one app with a given package name can be installed on a phone at a time, and Google Play uses it to tell apps apart. The display name and icon can be copied by anyone. The package name is what the system actually tracks.
Next come the <uses-permission> lines. Android sorts permissions into levels:
- Normal permissions carry little risk to your privacy, like internet access or setting an alarm. They're granted automatically when you install the app, with no prompt.
- Dangerous permissions (Google's own term) cover private data and sensors, such as location, microphone, camera, contacts, call logs and text messages. The app has to ask you at runtime, and you can say no.
Some normal permissions still deserve a look. RECEIVE_BOOT_COMPLETED, for example, lets an app be told when the phone finishes starting up, so it can start background work without you opening it. A sync service might need that. A simple calculator doesn't.
Reading permissions is about fit. Ask whether each one makes sense for what the app says it does. A notes app that wants photos for picture notes is reasonable. A notes app that wants your text messages is not.
On the simulated phone, tap each highlighted line of the QuickNotes manifest. Count how many of its requested permissions would make the app show you a permission prompt.
Components and open doors
The rest of the manifest lists the app's components, the building blocks Android can start on the app's behalf. There are four kinds:
- Activities, the screens you see
- Services, work that runs without a screen, like syncing
- Broadcast receivers, which react to system events such as the phone finishing booting
- Content providers, which share structured data, like a list of notes
A component can carry an intent-filter. An intent is a message asking Android to do something, such as "open the main screen" or "send this text". The filter advertises which intents the component can handle. The filter with MAIN and LAUNCHER is what puts an app's icon in your app drawer. A SEND filter is how an app appears in the share sheet.
The android:exported attribute decides who can reach a component. If it's true, any app on the phone can start it. If it's false, only the app itself, apps sharing its user ID and privileged system parts can. Since Android 12, apps must state this value explicitly for any activity, service or receiver with an intent-filter, because forgetting it used to leave doors open by accident.
An exported component isn't automatically a bug. The launcher screen has to be exported. But every exported component is a door other apps can knock on, so a careful developer keeps the list short and checks what comes through.
Finally, android:allowBackup controls whether the app's private data can be included in backups, such as Google Drive backup. For a notes app that may be helpful. For an app holding secrets, developers often turn it off or exclude sensitive files. On Android 12 and later, turning it off stops cloud backups but not device-to-device transfers to a new phone, so developers use separate backup rules to exclude sensitive files from those.
Remember the limits. The manifest shows what an app can ask for and which doors exist. It doesn't prove what the code does with them.
Can you answer these?
- How many of the permissions QuickNotes requests would trigger a runtime prompt?
- A service is declared with android:exported="false". Which apps can start it?
Answer them in the app to earn 60 XP.
Answer in the app