Back to skill

Security audit

mobile-security

Security checks for vulnerabilities and agentic risk

Overview

This skill provides scoped mobile-app security reviews, with no evidence of hidden credential collection, automatic changes, or background activity.

Limit the audit to authorized app repositories and keep discovered secrets redacted. Review suggested fixes before applying them. The scanner's unresolved references mostly name target-app files and example paths; all four bundled references were inspected. Static review still leaves runtime behavior to verify.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (23)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 107)May include surrounding context.

md
// BAD
UserDefaults.standard.set(token, forKey: "refreshToken")

// GOOD: Keychain, not migrated to other devices or backups
let query: [String: Any] = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrService as String: "com.example.auth",

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 124)May include surrounding context.

// GOOD const storage = FlutterSecureStorage( iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock_this_device), ); await storage.write(key: 'refresh_token', value: token);

text

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 236)May include surrounding context.

md
showVault()
}

// GOOD: Keychain item protected by access control; the OS releases it only after biometry
let access = SecAccessControlCreateWithFlags(
    nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .biometryCurrentSet, nil)
// add with kSecAttrAccessControl: access; read with kSecUseAuthenticationContext off the main thread

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 379)May include surrounding context.

md
- [ ] Cleartext disabled; no trust-all managers, hostname verifiers or `badCertificateCallback`
- [ ] MQTT and other IoT channels use TLS; BLE commands authenticated, not only CRC-checked
- [ ] Pinning, if present, has backup pins, expiry and a rotation plan
- [ ] Biometric auth bound to a `CryptoObject` or Keychain access control
- [ ] OAuth via system browser with PKCE; authorization enforced server-side
- [ ] Every exported component, deep link and App / Universal Link validated
- [ ] WebView bridges origin-scoped; file access off; untrusted URLs not loaded

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/flutter.md (reported line 41)May include surrounding context.

dart
const storage = FlutterSecureStorage(
  iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock_this_device),
);
await storage.write(key: 'refresh_token', value: token);

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/ios.md (reported line 39)May include surrounding context.

md
- `ThisDeviceOnly` items are not restored onto a different device from a backup.
- Keychain items can survive app deletion. Clear stale credentials on first launch after install
  (detect with a flag in `UserDefaults`, which is removed on uninstall).
- Shared access across your apps uses a Keychain access group entitlement; keep it as narrow as possible.

## Biometric-bound Keychain item

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/ios.md (reported line 58)May include surrounding context.

md
kSecValueData as String: secret,
    ]
    let status = SecItemAdd(query as CFDictionary, nil)
    guard status == errSecSuccess else { throw KeychainError(status: status) }
}

// Blocks while the system prompt is shown: never call on the main thread.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/ios.md (reported line 74)May include surrounding context.

] var result: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &result) guard status == errSecSuccess, let data = result as? Data else { throw KeychainError(status: status) } return data }

text

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 249)May include surrounding context.

  • OAuth / OIDC uses the system browser (Custom Tabs, ASWebAuthenticationSession) with PKCE, not an embedded WebView. Passkeys via Credential Manager or AuthenticationServices where supported.
  • Short-lived access tokens, refresh tokens in secure storage, server-side revocation on logout.
  • Authorization is enforced by the backend. A hidden button or a local isAdmin flag is not access control.
kotlin

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 40)May include surrounding context.

md
[MASVS controls and Top 10 map](references/masvs-map.md).
   For CRA, RED delegated act / EN 18031 or GDPR questions, hand the findings to `mobile-eu-compliance`.
   - Android: merged release manifest, network security config, backup rules, release build type, catalogs.
   - iOS: `Info.plist`, entitlements, `PrivacyInfo.xcprivacy`, `.xcconfig`, lock files. Flutter: both of these.
3. Run the quick-scan patterns from the references. Each hit is a candidate, not a finding.
4. Walk the MASVS categories in order: STORAGE, CRYPTO, AUTH, NETWORK, PLATFORM, CODE, RESILIENCE, PRIVACY.
   Read the full code path for every candidate, not just the matching line.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 68)May include surrounding context.

1. No secrets in the app package (MASVS-CRYPTO-2, MASVS-AUTH-1, M1)

Everything in an APK, IPA or Flutter bundle is readable: BuildConfig, strings.xml, Info.plist, .xcconfig, assets, --dart-define values. Obfuscation does not change that.

kotlin

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 80)May include surrounding context.

text

```swift
// BAD: Info.plist and xcconfig values ship in plain text
let key = Bundle.main.object(forInfoDictionaryKey: "BROKER_PASSWORD") as? String

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 243)May include surrounding context.

text

- `BIOMETRIC_STRONG` for crypto-bound auth. `setInvalidatedByBiometricEnrollment(true)` and `.biometryCurrentSet`
  invalidate the key on new enrollment. iOS requires `NSFaceIDUsageDescription` in `Info.plist`.

### 7. Sessions are controlled by the server (MASVS-AUTH-1, M3)

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 371)May include surrounding context.

md
## Checklist

- [ ] Threat model and data classification written down before findings
- [ ] Release manifest, `Info.plist`, entitlements, network config and build types reviewed
- [ ] No privileged secrets in code, resources, `BuildConfig`, `Info.plist`, `--dart-define` or git history
- [ ] Tokens and keys in Keystore / Keychain-backed storage; no new `security-crypto` usage
- [ ] Keychain accessibility class and Android backup rules checked

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 372)May include surrounding context.

md
- [ ] Threat model and data classification written down before findings
- [ ] Release manifest, `Info.plist`, entitlements, network config and build types reviewed
- [ ] No privileged secrets in code, resources, `BuildConfig`, `Info.plist`, `--dart-define` or git history
- [ ] Tokens and keys in Keystore / Keychain-backed storage; no new `security-crypto` usage
- [ ] Keychain accessibility class and Android backup rules checked
- [ ] No secrets or personal data in release logs; `FLAG_SECURE` or snapshot cover on sensitive screens

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ios.md (reported line 3)May include surrounding context.

md
# iOS security reference

Load this for Swift, Objective-C, `Info.plist`, `.entitlements`, `.xcconfig` and `PrivacyInfo.xcprivacy`.
Call out every `Info.plist` and entitlement change explicitly in the report; they affect App Review,
signing and provisioning.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ios.md (reported line 4)May include surrounding context.

md
# iOS security reference

Load this for Swift, Objective-C, `Info.plist`, `.entitlements`, `.xcconfig` and `PrivacyInfo.xcprivacy`.
Call out every `Info.plist` and entitlement change explicitly in the report; they affect App Review,
signing and provisioning.

## Quick scan

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ios.md (reported line 11)May include surrounding context.

md
| Pattern | Why | Usual severity |
|---|---|---|
| Keys like `API_SECRET`, `PASSWORD`, `TOKEN` in `Info.plist` or `.xcconfig` | Secret in the IPA | Critical if privileged |
| `NSAllowsArbitraryLoads` = YES | ATS disabled globally | High, needs App Review justification |
| `NSExceptionAllowsInsecureHTTPLoads`, `NSExceptionMinimumTLSVersion` lowered | Cleartext or weak TLS for a domain | High |
| `.useCredential` with `serverTrust` and no `SecTrustEvaluateWithError` | Trust-all | Critical |

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ios.md (reported line 15)May include surrounding context.

md
| `NSAllowsArbitraryLoads` = YES | ATS disabled globally | High, needs App Review justification |
| `NSExceptionAllowsInsecureHTTPLoads`, `NSExceptionMinimumTLSVersion` lowered | Cleartext or weak TLS for a domain | High |
| `.useCredential` with `serverTrust` and no `SecTrustEvaluateWithError` | Trust-all | Critical |
| `UserDefaults` / `@AppStorage` with token, password, PIN | Plaintext plist | Medium |
| `kSecAttrAccessibleAlways` / `kSecAttrAccessibleAlwaysThisDeviceOnly` | Deprecated, readable while locked | Medium |
| `evaluatePolicy(` result used as the only gate | Hookable boolean | High for secrets or payments |
| `print(`, `NSLog(`, `privacy: .public` with personal data | Leak via device logs | Medium |

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ios.md (reported line 83)May include surrounding context.

md
- `.userPresence` allows passcode fallback; choose deliberately and document it.
- For signing use cases, create a Secure Enclave key (`kSecAttrTokenIDSecureEnclave`) with the same access
  control and have the server verify signatures.
- `NSFaceIDUsageDescription` is required in `Info.plist` when Face ID is used.

## Files and data protection

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ios.md (reported line 99)May include surrounding context.

Network

xml
<!-- Info.plist: ATS on by default; pin only domains you control -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSPinnedDomains</key>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ios.md (reported line 127)May include surrounding context.

md
- Custom trust evaluation must call `SecTrustEvaluateWithError` and only then compare pins.
- Apple platforms require Certificate Transparency for publicly trusted TLS certificates, so standard
  validation already rejects many mis-issued certificates.
- ATS exceptions in `Info.plist` need a justification at App Review; local-network IoT devices are a valid
  case only for the specific local domain or `NSAllowsLocalNetworking`, never a global exception.
- Local network access to IoT devices needs `NSLocalNetworkUsageDescription`.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · references/android.md (reported line 19)May include surrounding context.

md
| `tcp://` broker URI, port `1883` | Cleartext MQTT | Critical |
| `EncryptedSharedPreferences`, `EncryptedFile`, `MasterKey` | Deprecated library | Low (migrate), not a vulnerability by itself |
| `getSharedPreferences(` / DataStore keys named token, password, pin | Plaintext secrets | Medium |
| `MODE_WORLD_READABLE`, `MODE_WORLD_WRITEABLE` | Other apps read the file | High (throws on modern targets) |
| `getExternalStorageDirectory`, `getExternalFilesDir` with sensitive data | Shared or removable storage | Medium |
| `android:exported="true"` | Entry point for other apps | Review each |
| `android:allowBackup="true"` without `dataExtractionRules` | Tokens restorable to another device | Medium |