MyFamilyTracker
Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.
A practical walk through the OWASP Mobile Top 10 from an Android developer's chair — the risks that actually show up in real apps, with concrete Kotlin examples of what to do instead of the insecure default.
On this page
Security checklists are easy to nod along to and hard to act on. The OWASP Mobile Top 10 is useful precisely because it's concrete: each item maps to a mistake real apps ship. Here's how the list looks from an Android developer's perspective, with the fixes I actually apply rather than the abstract advice.
Hardcoded API keys and tokens in source are the classic. They end up in your APK, which anyone can unzip and
strings// Wrong: shipped in the APK, trivially extracted
const val API_KEY = "sk_live_abcd1234"
// Better: proxy through your backend so the secret never leaves the server
suspend fun fetchData() = api.getData() // backend holds the real keyEvery dependency is code you didn't write running with your app's permissions. I pin versions, review what a library actually pulls in, and run credential scans so a compromised transitive dep doesn't quietly exfiltrate data.
Trusting the client to enforce who-can-do-what is the bug. The app can hide a button, but the server must enforce the rule. Client-side checks are UX, not security.
Anything crossing a trust boundary gets validated. For local data and WebViews this matters more than people expect.
webView.settings.javaScriptEnabled = false // enable only if you must
webView.settings.allowFileAccess = false // block file:// readsAll network traffic is HTTPS, and I block cleartext explicitly so a misconfigured endpoint can't silently downgrade.
<!-- network_security_config.xml -->
<network-security-config>
<base-config cleartextTrafficPermitted="false" />
</network-security-config>For high-value endpoints, certificate pinning raises the cost of a man-in-the-middle attack.
Collect the minimum. Every field you store is a field you must protect and declare in the Play Store data safety section. The cheapest data to secure is the data you never collected.
R8 with obfuscation is the baseline. It won't stop a determined reverse engineer, but it removes the easy wins — readable class names, obvious method paths.
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
}
}Exported components are the usual leak. An
ActivityReceiverexported="true"No secrets in plain
SharedPreferencesEncryptedSharedPreferencesUse the platform primitives correctly instead of inventing your own. AES-GCM with a Keystore-backed key, never a hardcoded key or a homegrown cipher.
A top-ten list is only useful if it changes what you do, and the trap is treating it as a one-time audit you run before a big release and then forget. I've found it works better as a recurring lens. Every time I add a feature that touches the network, storage, or another app, I ask which items on this list the change could regress. A new caching layer? That's M9, insecure data storage. A new deep link? That's M8 and input validation. The list stops being homework and becomes a quick reflex applied at the moment the risk is introduced, which is the only time the fix is cheap.
The other thing worth internalizing is that these risks compound. A leaked API key (M1) is bad on its own, but combined with weak transport security (M5) and an exported component (M8), you've handed an attacker a chain instead of a single door. Defense in depth matters because no single control is perfect; you're trying to make the overall cost of an attack higher than the reward. For the kind of focused consumer apps I build, that usually means an attacker moves on to an easier target, which is exactly the outcome you want.
I also resist the urge to over-engineer security for threats my app doesn't face. A water-reminder app does not need the same hardening as a banking client, and pretending otherwise wastes effort that should go into shipping. The honest move is to match the controls to the actual data and the actual threat model: protect what's genuinely sensitive seriously, declare what you collect truthfully, and don't collect what you don't need in the first place. Most real-world mobile breaches trace back to a handful of boring mistakes on this list, not exotic attacks — which is good news, because it means doing the basics consistently puts you ahead of most apps on the store.
Sudarshan Chaudhari
AI Systems Builder / Product Engineer
Bangkok, Thailand
Solo Android developer with 13+ years in QA, building Android apps, AI automation systems, and developer tools at SudarshanTechLabs.
Related Posts
Related Apps
Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.
Building something? Available for Android dev and QA consulting.
Work with meComments — powered by Giscus