Skip to main content

FraudShield

A security and fraud-risk scanner for our mobile apps. Point it at source code (Flutter, Kotlin, SwiftUI, KMP) or a built app (.apk, .aab, .ipa). It reports weaknesses that attackers and scammers abuse, explains how each one gets abused, and tells you how to fix it.

  • Pure Python 3.8+, no dependencies, no internet (except the optional --deps check). Your code never leaves your computer.
  • Results are printed in the terminal and saved to an HTML report you can share. JSON and SARIF output are available for CI.
  • Every finding is mapped to the OWASP MASVS mobile security standard.

Install

brew install pipx && pipx ensurepath     # once, if you don't have pipx
pipx install fraudshield-mobile

Update later with pipx upgrade fraudshield-mobile.

Quick start

# Source code: one app, or a folder full of apps
fraudshield ~/code/wallet-app
cd ~/code/wallet-app && fraudshield .

# Built apps: scan what you are about to ship
fraudshield build/app/outputs/flutter-apk/app-release.apk
fraudshield build/ios/ipa/Wallet.ipa

# Everything at once, plus a dependency check
fraudshield ~/code/wallet-app app-release.apk Wallet.ipa --deps

Open fraudshield-report.html to see the full report. You can filter it by severity and search it. It also includes a checklist of server-side fraud controls to confirm with the backend team.

Why scan both source and the build?

Source scan finds Build scan finds
Insecure code: trust-all TLS, OTP/PIN checked in the app, tokens in SharedPreferences/UserDefaults, logging of PINs, weak crypto, WebView holes, bypass/test codes What actually ships: keys injected by CI or --dart-define, .env files bundled into Flutter assets, debug builds, the debug signing key, development provisioning profiles, missing obfuscation
Config: AndroidManifest, network security config, Info.plist, Gradle, CI build commands The compiled manifest and Info.plist, DEX strings, Flutter libapp.so, the iOS binary, bundled JSON/env files

Run the source scan on every pull request. Run the build scan on the release artifact before uploading it to the Play Store or App Store.

What it checks

Area Examples
Secrets AWS keys, private keys, Paystack/Stripe sk_live_, Flutterwave secret keys, MTN MoMo / Hubtel / M-Pesa credentials, FCM server keys, JWTs, Google API keys, signing passwords, .env and key.properties contents
Network Trust-all TrustManager or HostnameVerifier, badCertificateCallback => true, iOS trust-all challenge handlers, cleartext HTTP, ATS disabled, user CAs trusted, verbose HTTP logging (OkHttp, Ktor, Dio), staging URLs in release builds
Storage Tokens or PINs in SharedPreferences, DataStore, UserDefaults, @AppStorage, multiplatform-settings, shared_preferences, GetStorage or Hive; weak Keychain protection; secrets copied to the clipboard; world-readable files
Fraud logic OTP/PIN compared on the device, master/test OTPs and bypassOtp switches, KYC level or limits read from local storage, fees or totals computed in the app, WebViews opening URLs taken from deep links, custom-scheme deep links, intent redirection
Auth Biometric login that is only a yes/no (Frida-bypassable), PIN typed into a visible TextField
Crypto ECB/DES, MD5/SHA-1, hard-coded keys and IVs, predictable random OTPs
Platform Debuggable builds, allowBackup, exported components, risky permissions (READ_SMS, SYSTEM_ALERT_WINDOW…), UIFileSharingEnabled, old TLS
Missing defences Screenshot/screen-recording protection, root/jailbreak detection, certificate pinning, Play Integrity / App Attest / App Check, overlay (tap-jacking) protection, R8 or --obfuscate
Dependencies (--deps) Known vulnerabilities from OSV.dev in pubspec.lock, Gradle / libs.versions.toml and Package.resolved

Options

Option What it does
--fail-on high Exits with code 1 if any finding is high or worse. Use it in CI to block a release.
--min-severity medium Hides findings below medium.
--json out.json / --sarif out.sarif Machine-readable output. SARIF shows up in GitHub code scanning.
--html path.html / --no-html Changes where the report is saved, or turns the report off.
--deps Checks dependencies against OSV.dev. This sends package names and versions, nothing else.
--exclude "legacy/*" Skips paths. The option can be repeated.
--include-tests Also reports issues in test code. Secrets in tests are always reported.
--write-baseline fs-baseline.json / --baseline fs-baseline.json Accepts today's findings, then reports only new ones. Useful when adopting the tool on an older app.

Silencing a false positive

Add a comment on the line, or on the line above it. Always say why:

Log.d(TAG, "token refreshed")  // fraudshield:ignore LOG001 - no value logged

Debug-only code is skipped automatically: if (BuildConfig.DEBUG) { … }, if (kDebugMode) { … } and #if DEBUG … #endif.

Using it in CI

GitHub Actions:

- run: pipx install fraudshield-mobile
- name: FraudShield (source)
  run: fraudshield . --fail-on high --sarif fraudshield.sarif --html fraudshield.html
- name: FraudShield (release build)
  run: fraudshield build/app/outputs/flutter-apk/app-release.apk build/ios/ipa/*.ipa --fail-on high --no-html
- uses: github/codeql-action/upload-sarif@v3
  if: always()
  with: { sarif_file: fraudshield.sarif }
- uses: actions/upload-artifact@v4
  if: always()
  with: { name: fraudshield-report, path: fraudshield.html }

Codemagic or a shell script: pipx install fraudshield-mobile && fraudshield . --fail-on high || exit 1

Reading the grade

Grade Meaning
F At least one critical finding: attackers can exploit it now. Don't release.
D Three or more high findings.
C At least one high finding. Fix before release.
B Only medium or lower: hardening needed. Most apps without anti-tamper protection land here.
A No significant issues found.

Limits (please read)

  • The scanner matches patterns. It catches the common mistakes quickly, but it's not a penetration test. Some findings will need a human to confirm them, and some problems can't be seen by pattern matching.
  • It can't see your backend, and most real fraud losses come from missing server-side controls: amount and fee recomputation, idempotency, OTP limits, IDOR checks, SIM-swap checks, velocity rules. The HTML report ends with a checklist for these.
  • For built apps:
    • Native FLAG_SECURE is a numeric constant, so it can't be seen in a build. Confirm it with a source scan.
    • App Store-downloaded IPAs are encrypted. Scan the IPA exported from Xcode or CI instead.
    • For .aab files the manifest isn't decoded. Use bundletool build-apks --mode=universal and scan the APK too.
  • Secret values are masked in all reports, so reports are safe to share.

Code layout

File What's in it
fraudshield/cli.py Command line: arguments, filtering, baseline, exit codes
fraudshield/rules.py Every detection rule, with its severity, explanation, fix and MASVS mapping, plus the defence markers. Most changes happen here.
fraudshield/scanner.py Rule engine, source-folder scanning, AndroidManifest / network-security-config / Info.plist / Gradle / CI checks, missing-defence checks, OSV dependency check
fraudshield/binary_scanner.py .apk / .aab / .ipa decoding: Android binary XML, DEX strings, Mach-O, signing certificate and provisioning profile, bundled assets
fraudshield/report.py Risk grade, terminal output, SARIF, HTML report, backend checklist

Development

python3 -m unittest discover -s tests -v      # 18 tests
python3 tests/make_test_apps.py               # builds vulnerable test APK/IPA into tests/build/
python3 fraudshield.py path/to/app            # run from this folder without installing

tests/fixtures/ contains small, deliberately vulnerable Flutter, Kotlin, SwiftUI and KMP apps, plus one clean app that must produce zero findings. The fake keys are inserted at test time, so the repo never contains anything that looks like a real secret and GitHub push protection won't block it. Binary tests build real APKs and an IPA with the Android SDK and Xcode, and are skipped on machines without them.

To add a rule, add an R(...) entry to RULES in fraudshield/rules.py, add a vulnerable line to a fixture, and assert it in tests/test_fraudshield.py. Keep the clean app clean.

Metadata

Release files for fraudshield-mobile 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fraudshield-mobile 1.0.0
File Size Uploaded Provenance Actions
fraudshield_mobile-1.0.0.tar.gz 51.7 kB Without provenance Details for fraudshield_mobile-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fraudshield-mobile 1.0.0
File Interpreter ABI Platform Actions
fraudshield_mobile-1.0.0-py3-none-any.whl Python 3 none any Details for fraudshield_mobile-1.0.0-py3-none-any.whl

Total release size: 101.8 kB

Release files / fraudshield_mobile-1.0.0.tar.gz

Download URL fraudshield_mobile-1.0.0.tar.gz
Size 51.7 kB
Tags Source
SHA-256 checksum
How to use checksums
3062e4fa2902ba9518869d4a60694ff224b62e101daa6dd59ef19107ac622afc
BLAKE2b-256 checksum
How to use checksums
151d55daa9ddc32c591dfa36b0c7fe36a4feacc1831e59baee857009a857fe74
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.9

Release files / fraudshield_mobile-1.0.0-py3-none-any.whl

Download URL fraudshield_mobile-1.0.0-py3-none-any.whl
Size 50.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1ef80d35c585837bb105479cdffc0295450fbd438b34250671369e2b22e17709
BLAKE2b-256 checksum
How to use checksums
9a00d70290192ff3aeabd736d234b7b29aecddb5fad8723b780c700ea11d114d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.9

Security for fraudshield-mobile 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page