Skip to main content

APK/IPA secret + endpoint scanner for vibe-coded mobile apps. Companion to Qualmly (qualmly.dev).

Project description

Qualmly Mobile Scanner — APK/IPA secret extraction

Single-file Python tool that unzips a packaged Android (.apk) or iOS (.ipa) build and scans every embedded text file for hardcoded secrets and backend URLs. Closes the function gap vs AuditYourApp's mobile reverse-engineering feature ($49/scan).

Status

Working v1. Run it on a real APK or IPA today. Catches ~80% of real-world secret leaks via plain-text grep at scale (which is how ~80% of secrets actually ship in mobile apps anyway).

What's done:

  • ✅ Auto-detects APK vs IPA format
  • ✅ Skips media/fonts/native libs (focuses on JS/JSON/plist/xml/config)
  • ✅ Same 9 secret patterns as the qualmly.dev Code Review (Anthropic, OpenAI, Stripe, AWS, GitHub PAT/classic, Slack, Google API, Supabase JWT)
  • ✅ Endpoint detection (Supabase, Firebase, localhost fallbacks)
  • ✅ Pretty-print + JSON output
  • ✅ Score + exit code (1 if any *_live secret found — useful for CI)
  • ✅ Stdlib only (zipfile + re); no install dependencies

What's NOT done (next iteration):

  1. Smali decompile for APK to reach obfuscated string constants. Add apktool integration. ~1 day.
  2. Mach-O binary string extraction for iOS apps where keys are baked into native binaries (not just JS bundles). Use nm or strings. ~1 day.
  3. Web upload UI — wrap as a Cloudflare Worker that accepts file upload, runs the same logic, returns a Qualmly-style report. Enables charging $9/scan via Stripe. ~2 days.
  4. Integration with qualmly.dev — add a "Mobile" mode tab next to App QA + Code Review. Could be a stub that links to the standalone scanner for now.

Install

# Recommended — installs into an isolated venv, exposes `qualmly-mobile` on PATH
pipx install qualmly-mobile

# Or vanilla pip if you prefer
pip install qualmly-mobile

No native dependencies. Stdlib only. Works on macOS, Linux, and Windows (Python 3.8+).

If you want to run from source instead, just clone this repo and call the script directly with python3 mobile-scanner/qualmly_mobile.py … — it has zero install dependencies.

Usage

# Scan an APK
qualmly-mobile /path/to/app.apk

# Scan an IPA
qualmly-mobile /path/to/MyApp.ipa

# JSON output for CI
qualmly-mobile app.apk --json

# Write JSON to file
qualmly-mobile app.apk --report scan.json

(If running from source: replace qualmly-mobile with python3 qualmly_mobile.py.)

Sample output:

  🔍 Qualmly Mobile Scan — myapp.apk
  ─────────────────────────────────────────────────
  Format:           APK
  Size:             14.2 MB
  Files scanned:    142 / 1387
  Score:            64/100  ██████░░░░
  Secrets found:    2
  Endpoints found:  4

  🔴 SECRETS:
     • Stripe publishable key             in  assets/index-Dp8DBQyP.js
       sample: pk_live_51TO… (107 chars total)
     • Supabase service-role JWT          in  assets/index-Dp8DBQyP.js
       sample: eyJhbGciOi… (240 chars total)

  🔵 ENDPOINTS:
     • Supabase project URL               →  https://abc1234567.supabase.co
       in assets/index-Dp8DBQyP.js
     • Localhost fallback                 →  http://127.0.0.1:3000
       in src/config.json
     ...

  Powered by Qualmly · qualmly.dev

Why a separate Python tool, not in the browser?

Two reasons:

  1. APK/IPA files are too big to upload to a browser-side scanner reliably. 50–500 MB is typical. A native CLI runs locally on the build artifact without uploading.
  2. CI/CD friendly. Drop into GitHub Actions / Bitrise / Codemagic. Exit code 1 fails the build on live keys.

A hosted version (web upload) is on the roadmap — that gets bundled into the Agency tier or charged $9/scan as a separate Mobile tier.

Roadmap

Phase Scope ETA after launch
v1 (this scaffold) CLI tool, secrets + endpoints — Ready to ship now
v1.1 apktool / smali integration for APK 1 week
v1.2 Cloudflare Worker hosted upload, $9/scan 2 weeks
v2 Mach-O binary scanner (iOS native), mobile-specific findings (root detection bypass, certificate pinning checks) 4–6 weeks

Publishing a new version (maintainer notes)

Releases are published to PyPI via GitHub Actions Trusted Publishing (OIDC) — no PYPI_API_TOKEN secret needed once the project is registered.

One-time setup on PyPI:

  1. Create the project skeleton: build + upload the first release with a manual API token (twine upload mobile-scanner/dist/*), OR pre-register it via Trusted Publishing's "pending publisher" flow at https://pypi.org/manage/account/publishing/ → add publisher with:
    • PyPI Project Name: qualmly-mobile
    • Owner: DarkPixel-Z
    • Repository name: qualmly
    • Workflow name: publish-mobile-pypi.yml
    • Environment name: pypi
  2. In the GitHub repo, create a pypi environment (Settings → Environments) so the workflow's environment: pypi clause resolves.

Cutting a release:

# bump __version__ in qualmly_mobile.py and version in pyproject.toml
git add mobile-scanner/qualmly_mobile.py mobile-scanner/pyproject.toml
git commit -m "mobile-scanner: bump to v1.0.1"
git tag mobile-v1.0.1
git push origin main --tags

The Publish qualmly-mobile to PyPI workflow fires on the tag, builds sdist + wheel, runs twine check, then uploads via OIDC.

License

MIT — same as the parent project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qualmly_mobile-1.0.1.tar.gz (9.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qualmly_mobile-1.0.1-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file qualmly_mobile-1.0.1.tar.gz.

File metadata

  • Download URL: qualmly_mobile-1.0.1.tar.gz
  • Upload date:
  • Size: 9.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for qualmly_mobile-1.0.1.tar.gz
Algorithm Hash digest
SHA256 91c6589d7d0541e16421d1dc8c9a71071c9ee5896a19914e50cda948a9779090
MD5 27bf91d0d0ae76b81b38652098145283
BLAKE2b-256 4d7c01ae907283480c0fa7e17cc70912ce13f9609a9723c8e87e66d615863533

See more details on using hashes here.

Provenance

The following attestation bundles were made for qualmly_mobile-1.0.1.tar.gz:

Publisher: publish-mobile-pypi.yml on DarkPixel-Z/qualmly

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qualmly_mobile-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: qualmly_mobile-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 9.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for qualmly_mobile-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 74a62d8b8540e100614f7e985f590343cca583b3d0469f3a469c95f829f20ec6
MD5 aefa428f47215d1933ca54b7e367359a
BLAKE2b-256 170a26c6767d72539eba9f0f5f710846cb8b568c7825efa395eadbb78fa22679

See more details on using hashes here.

Provenance

The following attestation bundles were made for qualmly_mobile-1.0.1-py3-none-any.whl:

Publisher: publish-mobile-pypi.yml on DarkPixel-Z/qualmly

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page