§ Example report
com.insecureshop
v1.0
This is a deliberately-vulnerable demo app. Run the same 88 analyzers on your release APK — your first scan is free.
Scan your app — free, no cardSeverity breakdown
4 crit 4 high 28 med 6 low 0 info
Critical 4
High 4
Medium 28
Low 6
Info 0
False positives 0
Scan metadata
Package
com.insecureshop
Version
1.0
Size
4.5 MB
SHA-256
a83298ae4a37fcab8101e8b41e513dd2199af71a94ea537d556a318e07d4d1bd
Findings
93
Started
Sep 20, 2026
2:48:59 AM
Finished
Sep 20, 2026
2:49:59 AM
Duration
1m
Sandbox image
atomic-scanner-sandbox:dev
OWASP Mobile Top 10 (2024) — coverage
Click a category to filter the findings list.
Vulnerabilities 42
Sev Title OWASP / MASVS Plugin Description
M8 MASVS-PLATFORM
platform.webview
3 instances — click to expand
critical
WebView accepts every TLS error in com.insecureshop.util.CustomWebViewClient (onReceivedSslError → handler.proceed)
M5 MASVS-NETWORK
network.webview_ssl_error_proceed
`com.insecureshop.util.CustomWebViewClient.onReceivedSslError` calls `SslErrorHandler.proceed()` — the WebView accepts the navigation despite a TLS error (invalid cert, expired cert, hostname mismatch, …). This is permanent MITM: any attacker can present any cert and the WebView will load the page, including JavaScript that reads cookies, shared-prefs (via `JavascriptInterface`), or saved-form values.
high
Application is debuggable
M7 MASVS-CODE
manifest.security_attributes
`android:debuggable="true"` is set on `<application>`. Debug builds expose JDWP, allow attaching a debugger to any process, and bypass platform tamper-detection paths — a release APK in this state is trivially modifiable on any unrooted device.
high
Cross-package code loading via createPackageContext in com.insecureshop.LoginActivity
M7 MASVS-CODE
code.dynamic_code_loading
`void com.insecureshop.LoginActivity.onLogin(View)` calls `Context.createPackageContext(...)` with flags `0x3` (CONTEXT_INCLUDE_CODE, CONTEXT_IGNORE_SECURITY). `CONTEXT_IGNORE_SECURITY` disables the caller-signature check, so code is loaded from another package even when it is signed by a different key. `CONTEXT_INCLUDE_CODE` loads and can run that package's DEX inside THIS app's process. An attacker who can install, replace, or spoof the package name of another package then executes arbitrary code with this app's identity and permissions (CWE-940: improper verification of source of a communication channel / cross-package code loading).
high
Signed with Android SDK debug key (CN="Android Debug")
M7 MASVS-RESILIENCE
resilience.apk_signing
The certificate's Common Name matches the Android SDK's well-known debug key. Production builds signed with this key share an identity with every other `android-debug-key`-signed app — the package signature no longer uniquely identifies your release, breaking signature-permission models, KeyStore key separation, and Play Store upload verification.
high
Weak signing key: RSA 1024 (< 2048)
M7 MASVS-RESILIENCE
resilience.apk_signing
The signing certificate uses RSA with a 1024-bit key — below the 2048-bit floor current NIST guidance considers acceptable. Modern Android signing should use RSA-2048+ (preferably 4096), or EC-P-256+.
M8 MASVS-PLATFORM
manifest.security_attributes
5 instances — click to expand
M4 MASVS-PLATFORM
platform.deep_link_input
4 instances — click to expand
M8 MASVS-PLATFORM
platform.dynamic_receiver
2 instances — click to expand
M8 MASVS-PLATFORM
platform.intent_redirection
2 instances — click to expand
M9 MASVS-STORAGE
storage.logging_pii
2 instances — click to expand
M9 MASVS-PLATFORM
platform.flag_secure
2 instances — click to expand
medium
Cleartext (HTTP) traffic is permitted
M5 MASVS-NETWORK
manifest.security_attributes
`android:usesCleartextTraffic="true"` opts the entire app out of Android's default cleartext block (on by default for targetSdk≥28). Any HTTP request the app makes is observable and modifiable by a network-path attacker.
medium
Credential written to plaintext storage in com.insecureshop.util.Prefs
M9 MASVS-STORAGE
code.native_bridge
`com.insecureshop.util.Prefs.setPassword` persists a credential into SharedPreferences.Editor.putString of a password without at-rest encryption. Data written to SharedPreferences, a DataStore, or a SQLite database in plaintext is readable by anyone who can reach the app's private storage — a backup extraction, a rooted device, an `adb backup`-eligible app, or a debuggable build.
medium
Credential-bearing Intent dispatched via startActivity
M8 MASVS-PLATFORM
platform.implicit_intent_leak
`void com.insecureshop.CustomReceiver.onReceive(Context, Intent)` calls `startActivity` with an Intent that the taint analyzer traces back to a `putExtra(...)` call carrying credential-shaped data. If this Intent is dispatched implicitly — no `setComponent` or `setPackage` on the same register — any app declaring a matching `<intent-filter>` (including a hostile one) receives the extras. Static analysis can't always tell whether the Intent was scoped; the `requires_review: true` evidence flag flags this callsite for manual confirmation.
medium
Exported provider without permission: com.insecureshop.contentProvider.InsecureShopProvider
M8 MASVS-PLATFORM
manifest.security_attributes
The provider `com.insecureshop.contentProvider.InsecureShopProvider` is exported (or implicitly exported via its intent-filter) and declares no `android:permission` to gate access. Any other app on the device can launch / bind to / call into it without consent. It sets `android:readPermission` but no `android:writePermission` or `android:permission`, so any app can still WRITE to it (data injection / integrity risk).
medium
Exported service without permission: net.gotev.uploadservice.UploadService
M8 MASVS-PLATFORM
manifest.security_attributes
The service `net.gotev.uploadservice.UploadService` is exported (or implicitly exported via its intent-filter) and declares no `android:permission` to gate access. Any other app on the device can launch / bind to / call into it without consent.
medium
FileProvider shares an over-broad `root-path`: androidx.core.content.FileProvider
M8 MASVS-PLATFORM
platform.content_provider_audit
The `FileProvider` `androidx.core.content.FileProvider` (authority `com.insecureshop.file_provider`) declares `android:grantUriPermissions="true"` and its `<paths>` resource (`res/xml/provider_paths.xml`) contains `<root-path path="/"/>`, which shares the entire device filesystem the app's UID can read (`/`). A grantable `FileProvider` hands any app that receives a `content://` URI (via `FLAG_GRANT_READ_URI_PERMISSION` / `FLAG_GRANT_WRITE_URI_PERMISSION`) temporary access to files beneath the shared root. With the whole base directory exposed, a caller that obtains — or coerces the app into issuing — such a grant can reach files far beyond what the sharing feature intended — the app's whole internal files directory for a bare `files-path`, up to the app's own private data when the shared root is the filesystem root.
medium
Hardcoded login credentials in com.insecureshop.util.Util.getUserCreds()
M1 MASVS-AUTH
auth.hardcoded_credentials
`com.insecureshop.util.Util.getUserCreds()` builds a credential map from two hardcoded string literals, mapping `shopuser` → `!ns3csh0p` via `java.util.Map.put(...)`. Both the username/key and the password/value are compiled into the APK, so anyone who unpacks the app (a one-command `unzip` + `baksmali`) recovers the credential verbatim. A secret baked into client bytecode is shared by every install and cannot be rotated without shipping a new build — the classic hardcoded-credential (“backdoor login”) weakness, CWE-798.
medium
Outdated targetSdkVersion (29)
M8 MASVS-CODE
code.sdk_versions
`targetSdkVersion=29` is more than two Android releases behind the current API level (35). The app opts out of platform-side hardening shipped in newer releases (scoped storage, runtime broadcast restrictions, permission auto-revoke, mutable PendingIntent default flip, …) and is likely to be rejected by Google Play under their rolling target-API requirement.
medium
Sensitive activity com.insecureshop.LoginActivity has no tapjacking protection
M8 MASVS-PLATFORM
platform.tapjacking
`com.insecureshop.LoginActivity` looks like a sensitive screen (credential entry) but no class in its hierarchy calls `setFilterTouchesWhenObscured(true)`. A malicious overlay drawn via `SYSTEM_ALERT_WINDOW` or injected by a hostile accessibility service can capture taps that look like they land on the legitimate UI.
medium
Untrusted Intent/Uri input reaches a filesystem path (new File()) in com.insecureshop.ChooserActivity
M4 MASVS-PLATFORM
platform.path_traversal
`void com.insecureshop.ChooserActivity.onCreate(Bundle)` builds a filesystem path via `java.io.File(String)` from data the taint analyzer traces back to incoming IPC input (`Intent.get*Extra` / `getData` / a `Uri` path part / `Bundle.getString`). The sender controls that string: a value like `../shared_prefs/prefs.xml` escapes the intended directory (path traversal, CWE-22), and even without `..` it can name a private file the feature never meant to expose — the MASTG-DEMO-0122 pattern, where an extra picks the file a `FileProvider` then shares. `com.insecureshop.ChooserActivity` is an exported activity, so any app on the device can send it this input.
This is an intra-procedural taint result flagged for review — confirm the resolved path is not canonicalised and checked against the intended base directory before it is used.
medium
User-installed CAs implicitly trusted (minSdk 16, no NSC)
M5 MASVS-NETWORK
network.nsc
The app declares `minSdkVersion=16` (< 24) and references no `android:networkSecurityConfig`. On Android releases before API 24 the platform default trust store includes **user-installed CAs**, so without an explicit config the app trusts any CA the user — or a corporate/MITM device-admin box — has installed. Such an attacker can transparently intercept the app's TLS traffic. From API 24 the default switched to system-only trust anchors, so this exposure applies specifically to the pre-24 install base. (This is the `minSdk < 24` counterpart of `manifest.no_network_security_config`, which covers the `targetSdk >= 24` no-NSC case — the two are disjoint.)
low
Auto-backup is enabled
M9 MASVS-STORAGE
manifest.security_attributes
`android:allowBackup="true"` lets `adb backup` extract the app's private data on a debug-bridged device, and (on Android <12) lets Auto Backup ship the same data to the user's Google Drive — tokens and credentials in `shared_prefs/` / `databases/` ride along. `android:fullBackupContent and dataExtractionRules` are not declared, so that backup path is unscoped and captures everything by default.
low
AWS Cognito identity pool ID in @string/aws_Identity_pool_ID
M1 MASVS-AUTH
auth.hardcoded_credentials
`@string/aws_Identity_pool_ID` contains a value matching the pattern for AWS Cognito identity pool ID. It is a `<string>` resource. `res/values/` strings ship in every APK and are trivially extracted with `apktool` or by reading `resources.arsc`. Anyone with the APK can read this value, but it isn't a rotatable secret — the exposure is mitigated at the source (tighten access control or restrict the key), not by rotation.
low
No anti-debug / signature-check signal found
M7 MASVS-RESILIENCE
resilience.tamper_detection
No reference to `Debug.isDebuggerConnected`, `PackageManager.checkSignatures`, or other classic tamper-detection APIs. For apps handling sensitive data MASVS-RESILIENCE expects at least one active-debugger check + a signature self-check.
low
No network security config declared
M5 MASVS-NETWORK
manifest.security_attributes
`android:networkSecurityConfig` is unset. The app falls back to the platform default trust store and has no per-domain policy hooks — no certificate pinning, no per-host cleartext restrictions, no debug-only trust anchors.
low
No obfuscation detected (60 app classes inspected, 2% short-named)
M7 MASVS-RESILIENCE
resilience.obfuscation_estimate
Of 60 app-owned classes (excluding framework / AndroidX / Kotlin / Google Play / OkHttp / Retrofit / RxJava / similar curated-out packages), only 2% carry single-character simple names — the share R8 / ProGuard typically produces. Class, method, and field names are intact, which gives a reverse engineer a free map of your business logic and accelerates RE of any custom anti-tamper / crypto / licensing code shipped with the app.
low
No root-detection signal found
M7 MASVS-RESILIENCE
resilience.tamper_detection
No reference to known root-detection libraries (RootBeer, SafetyNet, Play Integrity) and no su-path string constants in the DEX. For apps handling credentials, payments, or DRM content, MASVS-RESILIENCE-1 expects at least one runtime check + server-side attestation. Absence is a build-hygiene signal that the threat model didn't consider rooted devices.
Findings 8
Findings that need human review — the scanner can't confirm exploitability on its own. Severity varies: some are low-signal, others are real weaknesses worth confirming.
Sev Title OWASP / MASVS Plugin Description
M8 MASVS-PLATFORM
platform.implicit_intent_leak
4 instances — click to expand
M8 MASVS-PLATFORM
platform.deep_links
2 instances — click to expand
low
installed-app enumeration collected in com.insecureshop.LoginActivity
M6 MASVS-PRIVACY
privacy.hardware_identifiers
`com.insecureshop.LoginActivity` enumerates the set of installed apps via `PackageManager`. This is not a device identifier — it is app-inventory data that can fingerprint a user or reveal sensitive installed apps (banking, health, dating). On Android 11+ broad enumeration requires the `QUERY_ALL_PACKAGES` permission, which Google Play restricts to apps with a documented core need. Reported for reviewer disclosure, not as a vulnerability.
info
WebView used but no session-data cleanup found
M8 MASVS-PLATFORM
platform.webview
This app uses a WebView (`addJavascriptInterface`, `setJavaScriptEnabled`, or `WebView.loadUrl`) but the bytecode contains no call to any WebView session-cleanup API: `WebView.clearCache`, `WebView.clearHistory`, `CookieManager.removeAllCookies`, or `WebStorage.deleteAllData`. Without explicit cleanup, the WebView's cache, browsing history, cookies, and DOM storage can persist across logout / account switch — a local attacker or a subsequent user of the device may recover session tokens or rendered sensitive content. This is a coarse, app-level absence signal: the cleanup logic may live in a helper or a third-party library this static check can't see, so verify manually.
Security posture
0 present · 7 absent · 0 partialTransport
Screen capture
Anti-tampering
Build
App inventory
What the app is — declared permissions, bundled SDKs, signing, build config. Reference, not findings.
| Permission | Risk | Status | Note |
|---|---|---|---|
| READ_EXTERNAL_STORAGE | info | used | an API this permission gates is referenced in code |
| WRITE_EXTERNAL_STORAGE | info | used | an API this permission gates is referenced in code |
| READ_CONTACTS | medium | declared | not statically checkable for usage |
| Component | Kind | Version | Category | PII |
|---|---|---|---|---|
| Glide | library | — | — | — |
| Gson | library | — | — | — |
Signing
- Schemes
- v1, v2
- Key
- RSA 1024
- Subject
- Android Debug
- Validity
- —
- Issues
- Signed with Android SDK debug key (CN="Android Debug")Weak signing key: RSA 1024 (< 2048)
App profile
- minSdk/target
- 16 / 29
- Minification
- none (0.017)
- Network config
- absent
- Legacy storage
- —
- Native libs
- extracted: —
- StrictMode
- no
Other inventory (19)
- Framework: Native Android (confidence: low) code.framework_detection
- java.lang.Math.random() called in com.bumptech.glide.load.resource.gif.GifFrameLoader crypto.insecure_random
- 2 java.lang.Math.random() calls in void androidx.transition.Explode.calculateOut(View, Rect, int[]) crypto.insecure_random
- java.util.Random instantiated in kotlin.random.FallbackThreadLocalRandom.implStorage.1 crypto.insecure_random
- java.util.Random instantiated in kotlin.random.KotlinRandom crypto.insecure_random
- WebView.setJavaScriptEnabled(true) in com.insecureshop.PrivateActivity platform.webview
- WebView.setJavaScriptEnabled(true) in com.insecureshop.WebView2Activity platform.webview
- WebView.setJavaScriptEnabled(true) in com.insecureshop.WebViewActivity platform.webview
- App-scoped external-storage API used: Context.getExternalMediaDirs in androidx.core.content.FileProvider storage.external_storage_apis
- External-storage API used: Environment.getExternalStorageDirectory in androidx.core.content.FileProvider storage.external_storage_apis
- External-storage API used: Environment.getExternalStorageDirectory in androidx.core.os.EnvironmentCompat storage.external_storage_apis
- External-storage API used: Environment.getExternalStorageDirectory in com.insecureshop.ChooserActivity storage.external_storage_apis
- External-storage state query: Environment.getExternalStorageState (2 calls) in String androidx.core.os.EnvironmentCompat.getStorageState(File) storage.external_storage_apis
- App-scoped external-storage API used: Context.getExternalFilesDir in androidx.core.content.ContextCompat storage.external_storage_apis
- App-scoped external-storage API used: Context.getExternalFilesDirs in androidx.core.content.ContextCompat storage.external_storage_apis
- App-scoped external-storage API used: Context.getExternalCacheDir in androidx.core.content.ContextCompat storage.external_storage_apis
- App-scoped external-storage API used: Context.getExternalCacheDir in com.bumptech.glide.load.engine.cache.ExternalCacheDiskCacheFactory.1 storage.external_storage_apis
- App-scoped external-storage API used: Context.getExternalCacheDir in com.bumptech.glide.load.engine.cache.ExternalPreferredCacheDiskCacheFactory.1 storage.external_storage_apis
- App-scoped external-storage API used: Context.getExternalCacheDirs in androidx.core.content.ContextCompat storage.external_storage_apis