AppForShareOpen dashboard

Docs

Security scan

Every .apk and .ipa uploaded with an account is scanned at upload, in the same step as the store readiness check. An .aab is scanned as the APK made from it. There is nothing to turn on. The result shows on the build page under the readiness check, in the CLI, in the CI API and in the MCP server. Each finding has a level (to fix, warning or note), an OWASP MASVS category, a detail and a fix. The result is a count, such as 1 to fix and 3 warnings, never a percentage or a grade.

These are MASVS mapped checks on the file: findings and hints from a static scan. The scan never runs the app and adds nothing to it. It is not a penetration test, not a certification and not a compliance statement.

Both platforms

Secrets are matched on high confidence patterns only, in dex code, resources, assets, React Native bundles, Info.plist, the iOS main binary and Flutter compiled code. A library version is matched only when the build states it; it is never guessed. The advisory table was checked on November 8, 2026, and every entry links its public advisory.

CheckLevelMASVS
AWS access key ids, Stripe live secret and restricted keys, PEM private keys, Google service account JSON, Slack tokens, GitHub tokens, legacy Firebase Cloud Messaging server keysTo fixSTORAGE or CRYPTO
Slack webhook addressesWarningSTORAGE
Google API keys (meant to ship; restrict them to your app)NoteSTORAGE
Library versions with a public advisory: OkHttp 3.0.0 to 4.9.1, Play Core before 1.7.2, OpenSSL 1.0.1 to 1.0.1f and the CCS injection range, zlib 1.2.12 and earlier, AFNetworking before 2.5.3To fix, warning or note per advisoryCODE
Root, jailbreak, tamper and attestation checks present or absent (RootBeer, freeRASP, DexGuard runtime, JailMonkey, Play Integrity, Firebase App Check, App Attest, IOSSecuritySuite)NoteRESILIENCE

Android

CheckLevelMASVS
App data backed up without rules: allowBackup on or not set, and no dataExtractionRules or fullBackupContentWarningSTORAGE
Activities, activity aliases, services, receivers and providers exported without a permission (launcher activity left out, up to 20 listed)WarningPLATFORM
Network security config trusts user added certificates outside debug-overridesWarningNETWORK
Plain HTTP allowed for every serverWarningNETWORK
Debuggable buildWarningRESILIENCE
WebView debugging (setWebContentsDebuggingEnabled) referenced in the codeNotePLATFORM
Class names in classes.dex look unshrunk, so R8 or ProGuard probably did not run (native Kotlin and Java apps only, a hint)NoteRESILIENCE
Minimum API below 24 (Android 7.0)NoteCODE

iOS

CheckLevelMASVS
App Transport Security off for every domain (NSAllowsArbitraryLoads)WarningNETWORK
Each NSExceptionDomains entry, with what it loosens: plain HTTP, minimum TLS version, forward secrecy, subdomainsNoteNETWORK
Insecure loads allowed in web views (NSAllowsArbitraryLoadsInWebContent)NoteNETWORK
get-task-allow in a build that is not development signedWarningRESILIENCE
Local symbols left in the main binaryNoteRESILIENCE

What each plan shows

Free
The counts on every build ("1 to fix, 3 warnings, 2 notes") with a locked preview of the findings. The CI build answer carries the counts.
Pro
Every finding with its file, detail and fix; an AI fix plan (1 AI action, cached for the same build); appforshare security with --fail-on; the MCP tool get_security_scan; GET /api/ci/builds/{ref}/security.
Team
Everything in Pro, plus the full report grouped by MASVS category, export as JSON or a printable HTML page (dashboard, CLI --format, CI API), and the findings history across the builds of one app with what is new and what was fixed since the build before.

Plans and prices: pricing.

CLI

CLI 1.22.0 or later, with an API token from Dashboard, Settings (Pro and Team). --fail-on block exits with code 2 when the build has something to fix; --fail-on warn also on warnings. The build stays uploaded either way. A build that was not scanned never fails the gate.

# Print the findings of a build (id or slug)
npx appforshare security 12345

# Fail the job when something has to be fixed (exit code 2)
npx appforshare security 12345 --fail-on block

# Fail on warnings too
npx appforshare security 12345 --fail-on warn

# Machine readable
npx appforshare security 12345 --json

# Team: the full report as a file
npx appforshare security 12345 --format html --out security-report.html
npx appforshare security 12345 --format json --out security-report.json

What it prints (shortened):

Shop 3.2.0 (88)
Security scan: 1 to fix, 2 warnings, 1 note
  TO FIX [MASVS-STORAGE] Stripe live secret key in the build
      Found in assets/config.json (sk_l...9Qx2). ...
      Fix: ...
  WARN   [MASVS-STORAGE] App data is backed up (allowBackup on)
  WARN   [MASVS-PLATFORM] 2 exported components without a permission
  NOTE   [MASVS-RESILIENCE] No root or tamper detection found
  14 checks without findings.
Findings and hints from a static scan of the file, not a penetration test or a certification.

GitHub Actions

Upload with the GitHub Action, then gate on the scan with the CLI in the next step. Testers still get the link; the job fails so the team sees the finding.

- name: Share build
  id: share
  uses: appforshare/appforshare-action@v1
  with:
    token: ${{ secrets.APPFORSHARE_TOKEN }}
    file: app/build/outputs/apk/release/app-release.apk

- name: Security scan gate
  run: npx appforshare@latest security ${{ steps.share.outputs.slug }} --fail-on block
  env:
    APPFORSHARE_TOKEN: ${{ secrets.APPFORSHARE_TOKEN }}

CI API

GET /api/ci/builds/{ref} carries security with status, summary and counts on every plan. GET /api/ci/builds/{ref}/security returns the findings (Pro and Team), and /security/export?format=json or html the full report (Team). status is unknown for builds that were not scanned. Full reference: CI API.

GET https://appforshare.io/api/ci/builds/12345/security
Authorization: Bearer $APPFORSHARE_TOKEN

{
  "status": "scanned",
  "summary": "1 to fix, 2 warnings, 1 note",
  "counts": { "block": 1, "warn": 2, "info": 1 },
  "groups": [{ "masvs": "MASVS-STORAGE", "title": "Storage: ...", "counts": { ... } }],
  "capped": false,
  "findings": [{ "id": "sec.secret.stripe-live-secret", "level": "block", "masvs": "MASVS-STORAGE", "title": "...", "detail": "...", "fix": "..." }],
  "passed": ["..."]
}

MCP server

The read only tool get_security_scan returns the same findings to Claude, Cursor, Codex, VS Code or ChatGPT (MCP 1.0.9, Pro and Team). Ask "what did the security scan find in the newest Android build?" and the assistant can open the files it names in your repository. Setup: MCP server.

Questions

Do you store the secrets the scan finds?
No. Only the kind, the file and a masked value (first 4 and last 4 characters) are kept. The full value is never stored, logged or sent to the AI. Values that look like samples, such as keys with EXAMPLE in them, are skipped.
Why does an older build say Not scanned?
The scan runs at upload. Builds uploaded before November 8, 2026 were never read by it. Upload the build again to scan it.
Does the scan run my app?
No. It reads the .apk or .ipa as a file. It never installs or runs it, so it cannot see runtime behaviour, server side problems or traffic.
Does it protect my app?
No. It adds nothing to the app: no obfuscation, no code hardening and no runtime protection. It reports findings and hints. It is not a penetration test, not a certification and not a compliance statement.
Which files does it read?
Dex code, resources and assets on Android; Info.plist and the main binary on iOS; React Native bundles (index.android.bundle, main.jsbundle) and Flutter compiled code on both. Third party iOS frameworks are not scanned for secrets.
What if my build is very large?
The scan reads up to about 400 MB per build, 256 MB per file and 800 files, for up to 25 seconds, so uploads never wait on it. When a cap stops it, the result says part of the build was not read.

Overview and examples: security scan on every build. Guides: hardcoded API keys in an APK or IPA, OWASP MASVS for small app teams.