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.
| Check | Level | MASVS |
|---|---|---|
| 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 keys | To fix | STORAGE or CRYPTO |
| Slack webhook addresses | Warning | STORAGE |
| Google API keys (meant to ship; restrict them to your app) | Note | STORAGE |
| 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.3 | To fix, warning or note per advisory | CODE |
| Root, jailbreak, tamper and attestation checks present or absent (RootBeer, freeRASP, DexGuard runtime, JailMonkey, Play Integrity, Firebase App Check, App Attest, IOSSecuritySuite) | Note | RESILIENCE |
Android
| Check | Level | MASVS |
|---|---|---|
| App data backed up without rules: allowBackup on or not set, and no dataExtractionRules or fullBackupContent | Warning | STORAGE |
| Activities, activity aliases, services, receivers and providers exported without a permission (launcher activity left out, up to 20 listed) | Warning | PLATFORM |
| Network security config trusts user added certificates outside debug-overrides | Warning | NETWORK |
| Plain HTTP allowed for every server | Warning | NETWORK |
| Debuggable build | Warning | RESILIENCE |
| WebView debugging (setWebContentsDebuggingEnabled) referenced in the code | Note | PLATFORM |
| Class names in classes.dex look unshrunk, so R8 or ProGuard probably did not run (native Kotlin and Java apps only, a hint) | Note | RESILIENCE |
| Minimum API below 24 (Android 7.0) | Note | CODE |
iOS
| Check | Level | MASVS |
|---|---|---|
| App Transport Security off for every domain (NSAllowsArbitraryLoads) | Warning | NETWORK |
| Each NSExceptionDomains entry, with what it loosens: plain HTTP, minimum TLS version, forward secrecy, subdomains | Note | NETWORK |
| Insecure loads allowed in web views (NSAllowsArbitraryLoadsInWebContent) | Note | NETWORK |
| get-task-allow in a build that is not development signed | Warning | RESILIENCE |
| Local symbols left in the main binary | Note | RESILIENCE |
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.jsonWhat 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.