A sample report

This is what you get for a fictional app, PlantPal. Every key and project in it is invented. The first three findings are shown in full.

Check your own app free
TestersWiz · Production Readiness ReportSAMPLE REPORT

PlantPal

com.plantpal.app · version 1.4.2 · scanned 24 September 2026 · report TW-SAMPLE01
VERDICT

Fix before you release

Supabase service key shipped in the app (project qwxkzmhtr2plantpal01). Findings at this level expose data or privileged actions, or stop a store accepting the build, so fix them before you release.

1Critical
1High
2Medium
5Low
3Info
✓ 2 fixedsince 11 September 2026

Ready for Google Play?

2 things to fix before you submit. Checked against what the package shows. Only Google decides whether a build is accepted; this tells you what stands in the way.
  • Fix first
    Targets the Android version Google Play requires

    Targets API 34. Google Play requires API 36 for new apps and app updates (since 31 August 2026). See finding #4.

  • Ready
    Is a release build

    Not debuggable.

  • To do
    Permissions that may need a Play Console declaration

    2 permissions may need a declaration or review in Play Console (App content): READ_MEDIA_IMAGES, AD_ID. Declare each one you use, or remove the ones a library added that you do not. See findings #7, #8.

  • Fix first
    No critical or high security issues

    2 critical or high findings to fix before release. See findings #1, #2.

  • To do
    Data Safety form

    6 data types to declare, drafted from what the package shows. Add anything your own backend collects.

Summary

We analysed PlantPal 1.4.2, built with React Native (Expo). The analysis found 1 critical, 1 high, 2 medium, 5 low findings to act on, and set 4 aside with a stated reason (shown at the end). The most serious: Supabase service key shipped in the app (project qwxkzmhtr2plantpal01). This key bypasses row-level security. This is an automated static analysis: it cannot prove the absence of problems, and the section on what it could not check matters as much as the findings.

Application profile

What the package says about itself, before looking for problems.
Built withReact Native (Expo)
EngineHermes bytecode
Android APItargets 34 · min 24
Supabaseqwxkzmhtr2plantpal01
Firebaseplantpal-prod
Data-collecting SDKsGoogle Firebase Analytics, Sentry, Google AdMob
Where your own code isYour JavaScript/TypeScript is in assets/index.android.bundle (compiled to Hermes bytecode). Most of the Java in this app is React Native and library code.

Critical and high findings

#SeverityFinding
1CriticalSupabase service key shipped in the app (project qwxkzmhtr2plantpal01)
2HighOpenAI API key shipped in the app

Your to-do list

Work through these in order.
  • Supabase service key shipped in the app (project qwxkzmhtr2plantpal01): Rotate it now: with the new API keys, delete this secret key in Supabase → Project Settings → API Keys and create a new one; with the legacy JWT keys, rotating means changing the project's JWT secret, which also replaces the anon key.
  • OpenAI API key shipped in the app: Revoke the key at the provider now, then call the provider from your server (or an Edge Function) and have the app call that instead.
  • Unencrypted HTTP is allowed to every server: Remove android:usesCleartextTraffic="true".
  • Targets Android API 34, below Google Play's current requirement of 36: Raise targetSdkVersion to 36.
Compared with your scan on 11 September 2026
  • 2 fixed: The app is built as debuggable; Content provider PlantProvider is open to every app
  • 0 still open
  • 1 new: OpenAI API key shipped in the app

What the scan observed

Results read directly from the package. Most serious first; secrets are masked.
1
Criticalassets/index.android.bundle (in the compiled file's strings)

Supabase service key shipped in the app (project qwxkzmhtr2plantpal01)

CategorySecrets and keys
ConfidenceHigh
BasisObserved in the input

A Supabase service_role key (eyJ****) was found in assets/index.android.bundle (in the compiled file's strings).

ImpactThis key bypasses row-level security. Anyone who unzips the APK can read, change and delete every row in the database and every stored file.
JSON Web Token: eyJ****
Found at: assets/index.android.bundle (in the compiled file's strings)
How to fix itRotate it now: with the new API keys, delete this secret key in Supabase → Project Settings → API Keys and create a new one; with the legacy JWT keys, rotating means changing the project's JWT secret, which also replaces the anon key. Then move every call that needs it to a server or Edge Function. Removing it from the next build is not enough: every copy of this build still holds a working key until you rotate it.
2
Highassets/index.android.bundle (in the compiled file's strings)

OpenAI API key shipped in the app

CategorySecrets and keys
ConfidenceHigh
BasisObserved in the input

A OpenAI API key (sk-proj-****) was found in assets/index.android.bundle (in the compiled file's strings).

ImpactAnyone who unzips the APK can run requests billed to your account and, depending on the provider, read data sent through it.
OpenAI API key: sk-proj-****
Found at: assets/index.android.bundle (in the compiled file's strings)
How to fix itRevoke the key at the provider now, then call the provider from your server (or an Edge Function) and have the app call that instead.
3
MediumAndroidManifest.xml <application>

Unencrypted HTTP is allowed to every server

CategoryNetwork security
ConfidenceHigh
BasisObserved in the input

android:usesCleartextTraffic="true" is set on the application in AndroidManifest.xml.

ImpactAnything the app sends over http:// can be read or changed by anyone on the same network. This setting shows the app is ALLOWED to use HTTP; it does not show that it does.
<application android:usesCleartextTraffic="true" …> (AndroidManifest.xml)
How to fix itRemove android:usesCleartextTraffic="true". If one development host needs HTTP, allow only that domain, in a network security config used only by debug builds.
What a live test could confirmProxy the app's traffic and look for requests made over plain http://.
+ 9 more findings in the full report
  • Targets Android API 34, below Google Play's current requirement of 36
  • Development or staging address in the build: staging-api.plantpal.example
  • App data is included in device backups
  • READ_MEDIA_IMAGES may require a Play Console declaration or review
  • AD_ID may require a Play Console declaration or review
  • 3 data-collecting SDK(s) your Data Safety form must account for
  • 2 third-party libraries identified
  • The app requests 2 runtime (dangerous) permission(s)
  • Supabase anon key in the app (project qwxkzmhtr2plantpal01): safety depends on your RLS

Google Play and release considerations

Items that may need a Play Console declaration or review, or that may stop Play accepting a build. Only Google decides; nothing here predicts its decision.
#SeverityFinding
4MediumTargets Android API 34, below Google Play's current requirement of 36
7LowREAD_MEDIA_IMAGES may require a Play Console declaration or review
8LowAD_ID may require a Play Console declaration or review

Downgraded and set aside

These matched a rule but are explained by legitimate platform, framework or library behaviour. Each shows why. They are not counted above; read them if you want to check the reasoning.
LowDowngraded from Mediumexpo.modules.notifications.service.NotificationsService
Broadcast receiver NotificationsService accepts broadcasts from any appExported so it can receive BOOT_COMPLETED, MY_PACKAGE_REPLACED from the system; originates from expo-notifications. No change recommended: changing it could stop expo-notifications working.
InfoDowngraded from Lowandroid.permission.SCHEDULE_EXACT_ALARM
SCHEDULE_EXACT_ALARM may require a Play Console declaration or reviewUsed by expo-notifications to deliver scheduled notifications on time. Keep it if you schedule reminders or alarms at exact times; otherwise remove it.
MediumSet asidecom.plantpal.app.MainActivity
Activity MainActivity can be started by any appLauncher entry point: Android requires it to be exported so the home screen can start your app. No change recommended.
MediumSet asidecom/facebook/react/bridge/X.java:12
Possible hardcoded secretThis is a Kotlin/JVM type descriptor or class name, not a key: it matched a generic high-entropy pattern.

Your Data Safety form, pre-filled

A draft based only on what is visible in the package, with the reason for each line. Check it against what your app really does - you are responsible for what you declare.
CategoryData typeBecause ofHow sure
LocationPrecise locationpermission ACCESS_FINE_LOCATIONAllowed by a permission
Personal infoEmail addressSupabase project qwxkzmhtr2plantpal01 (if you use Supabase Auth)Likely, if you use it
Photos and videosPhotospermission READ_MEDIA_IMAGESAllowed by a permission
App activityApp interactionsGoogle Firebase Analytics (Analytics)Collected by an SDK
App info and performanceCrash logsSentry (Crash reporting)Collected by an SDK
Device or other IDsDevice or other IDspermission AD_ID, Google Firebase Analytics (Analytics)Collected by an SDK

What this scan did not check

Not tested
  • Your backend, APIs and servers: this scan reads the APK file only and connects to nothing.
  • Runtime behaviour: the app was not installed or run, so nothing here shows what it does when used.
  • Business logic and authorization: whether a signed-in user can reach another user's data depends on your backend.
  • Code the app downloads or loads at runtime, including over-the-air updates (Expo Updates, CodePush) and remote configuration.
  • Whether each finding is reachable in normal use: static analysis sees the code that exists, not the paths that run.
  • Supabase project qwxkzmhtr2plantpal01: its row-level security, grants, functions and storage policies are what protect user data, and were not tested. Run the Database Security Audit on it.
  • Firebase security rules (Firestore, Realtime Database, Storage): not visible in the APK and not tested.
  • Native libraries (.so files): only their readable strings were searched; their compiled code was not analysed.
  • Obfuscated or encrypted code, and code the decompiler could not recover, may hide patterns the analyzers look for.
What runtime or live testing could verify
  • Proxy the app's traffic and look for requests made over plain http://.
  • Proxy the release build's traffic and check whether this host is contacted.
  • Run `adb backup` or a device-to-device transfer on a test device and inspect what was copied.
  • Run the release build on a real device through an intercepting proxy to see which hosts it actually contacts, and over what.
  • Test your backend's access rules directly (for Supabase, run the Database Security Audit; then try requests with the anon key and as a second test user).

Methodology and limitations

  • The APK you uploaded was checked to be a genuine Android package (by its contents, not its name) and scanned in an isolated environment with no internet access. It was never installed or run.
  • It was decoded and decompiled, and open-source analyzers (apktool, jadx, mobsfscan, semgrep, gitleaks) read the manifest, the network security config, the decompiled code, resources, assets and the readable strings of compiled bundles.
  • Every observation was graded by TestersWiz's deterministic rules: the same APK always produces the same findings, severities and verdict. Known legitimate behaviour of Android, React Native, Expo, Flutter and common libraries is downgraded or set aside with the reason stated, never hidden.
  • Libraries are identified from version files and constants in the package; a library is only called vulnerable when its exact version matches a published advisory in a vulnerability database snapshot built into the scanner.
  • Secrets are shown masked (a recognisable prefix and ****). Where an AI model was used, it wrote explanations of these findings from a redacted summary; it did not see your app and could not add, remove or re-grade anything.

Static analysis sees what is in the package, not what the app does when it runs, and it cannot see your servers or backend. It reports what the evidence supports and can be wrong in both directions: a finding may not be exploitable in practice, and a problem may exist that no rule detects.

Report TW-SAMPLE01. Tracker signatures: the εxodus database (exodus-privacy.eu.org), Open Database License 1.0.

This report is an automated static analysis of one Android application package (APK), as submitted. Findings and their severities come from automated, rules-based analysis; where an AI model is used, it only writes explanations of those findings. The report may contain false positives and may miss vulnerabilities. It is not a penetration test, an audit, a certification, or a guarantee that your app or its backend is secure, and it is not legal, regulatory or compliance advice. The Data Safety draft and Google Play notes are guidance based only on what is visible in the package: you remain responsible for your app, for your declarations to Google Play and any other store, and for any change you make because of this report. Test every change before you release it. Provided under the TestersWiz Terms of Service, which limit our liability.

May we use analytics and ad measurement? Analytics (Vercel, and Ahrefs on our public pages) count page views without cookies. Ad measurement lets Google's tag on our public pages see which visits came from our Google ads, using a Google cookie. The site works the same either way. Cookie Policy · How Google uses data ·