Defending Your
Users
Mark Murphy, CommonsWare
mmurphy@commonsware.com | @commonsguy
Setting the Stage
-
You Are Not Your Users
- Your users’ security concerns may not resemble yours
- Take into account all use cases of your app
-
Security Is Determined By What Your Users Receive
- What you develop and what you deliver may differ
- Because your app is more than your own code
The Software Supply Chain
The Software Supply Chain
The Software Supply Chain
The Software Supply Chain
Your Code
Example Malware Defenses
FLAG_SECURE
(your windows and others)
- Be wary of autofill
-
Minimize IPC
- Verify partner apps: correct signature?
- Protect your inbound IPC endpoints
- Encrypted local storage (Jetpack, SQLCipher, etc.)
- SSL pinning (to your certificate or to your CA)
Your Code
Example Bugs
-
ZIP Directory Traversal for Code Injection
- Scripting
- Support multidex
- Sanitize inputs… particularly from the network
- Using framework
ExifInterface
Your Code
Issue Detection
- Good code reviews
-
Static Analysis Tools
-
Source vs. APK
-
Commercial vs. open source
-
Manual execution vs. integrate into Gradle/CI
- Security audits
Libraries
Threats
- Ordinary security flaws
- Intentional malware by the library author (Xavier, MDash)
-
Hacked Library
- Repository prioritization (AndroidAudioRecorder)
- Repository hack (RubyGems)
- MITM attack
Libraries
Mitigation Steps
- Static analysis tools (APK)
- Security audits
- Runtime detection via data access auditing
- Gradle dependency verification
- Private artifact repository
-
Compile Library From Source
- As a separate project
- As a module in main project
Libraries
Data Access Auditing
getSystemService(AppOpsManager::class.java)
?.setOnOpNotedCallback(executor, object : AppOpsManager.OnOpNotedCallback() {
override fun onNoted(op: SyncNotedAppOp) {
Log.d(TAG, "onNoted: ${op.toDebugString()}")
RuntimeException().printStackTrace(System.out)
}
override fun onSelfNoted(op: SyncNotedAppOp) {
Log.d(TAG, "onSelfNoted: ${op.toDebugString()}")
RuntimeException().printStackTrace(System.out)
}
override fun onAsyncNoted(op: AsyncNotedAppOp) {
Log.d(TAG, "onAsyncNoted: ${op.toDebugString()}")
RuntimeException().printStackTrace(System.out)
}
})
Development Process
Components
- Annotation processors
- Gradle plugins
- Gradle
Development Process
Threats
-
Attack Your Users
- Development-time malware injection, akin to hacked library
- Example: XCodeGhost
-
Attack You
- These components run on your development machine and CI server
- They can access and modify whatever you can access and modify
Development Process
Mitigation
- All the ones from libraries
- Avoid third-party Gradle Wrapper
- Inspect
distributionUrl
-
Private tools server
- Akin to private artifact repo, but for Gradle
- Gradle
distributionSha256Sum
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
distributionSha256Sum=10065868c78f1207afb3a92176f99a37d753a513dff453abb6b5cceda4058cda
You Are What You Sign
- APKs are digitally signed
-
What matters is key that signs the APKs that the user receives
- Updates must match on application ID and signing key
- APK cannot be altered without invalidating signature
-
Net: “Tamper-evident packaging”
- Nobody can tamper with APK after signing without being blocked
- Anyone with APK access before final signing can modify that APK
Third-Party Build Servers
-
Threats
- Real-time modification of APKs
- Extract signing keystore and passphrases
-
Mitigation Steps
- Don’t distribute APKs from a build server
- …Or, don’t sign APKs on the build server
- …Or, compare the APKs from the build server with local builds for differences
Google Play
Artifact Approaches
-
Developer-signed APKs
-
App Signing
- You sign the APKs
- Google removes your signature, modifies the APK
- Google re-signs the APKs for distribution
-
App Bundle
- Google creates the APKs, modifying them
- Google signs the APKs for distribution
Google Play
Ch-ch-ch-changes!
-
What We Know
- “Source stamp”
<meta-data>
in manifest
- App Bundles: subdivide based on resource splits, modules
-
Why Might Other Changes Be Made
- Because Google wants to, for some reason
-
Because Google is coerced
- Might not distribute changes to all users
Google Play
Mitigation Options
-
Sign Your Own APKs
- Avoid App Signing, App Bundles
- Problem: App Bundles a requirement for new apps in second half of 2021
-
Developer Inspection of APKs
- Problem: getting all the pieces
- Only works for changes distributed to everyone
- ¯\_(ツ)_/¯
In Conclusion
The End Is Near!
- Worry about your code
- Worry about others' code
- Worry about your tools
- Worry about your app distribution channels
Learn More!
Slides! Links to Resources! Exclamation Points!!!!?!
https://commonsware.com/presos/2020-10-AppDevSec/