Back to skill

Security audit

Mobile BLE

Security checks for vulnerabilities and agentic risk

Overview

This skill provides coherent Bluetooth app-development guidance with disclosed background behavior and safeguards for firmware updates.

Review generated permission and background-mode changes. Run firmware failure tests on dedicated hardware with a verified recovery procedure, checking that incompatible images and low battery block updates. If adopting the Flutter dependency, review its disclosed licensing and build-time data sharing.

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (13)

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 39)May include surrounding context.

md
If a packet format, opcode or timing is not written down, ask; never guess it.
2. **Read the project setup.**
   - Android: `minSdk`, `targetSdk`, manifest permissions, foreground service declarations.
   - iOS: deployment target, `Info.plist` usage strings, `UIBackgroundModes`, restoration identifier.
   - Flutter: `pubspec.yaml` BLE and permission plugins and their versions.
3. **Load the platform reference** for the code being touched:
   [Android](references/android.md), [iOS](references/ios.md), [Flutter](references/flutter.md).

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 50)May include surrounding context.

md
7. **Plan background behaviour** per platform: foreground service or Companion Device Manager on
   Android, `bluetooth-central` and state restoration on iOS.
8. **Test** with fakes behind an interface, then on real hardware. See [Testing](references/testing.md).
9. **Report** permissions, `Info.plist` keys, entitlements, foreground service types and background
   modes the change adds. These affect store review and signing and must be called out explicitly.

## Platform facts (verified)

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 96)May include surrounding context.

// BAD: CBCentralManager created at launch, before the user knows why; no usage string let central = CBCentralManager(delegate: self, queue: nil)

// GOOD: Info.plist has NSBluetoothAlwaysUsageDescription; create the manager when the feature starts if CBManager.authorization == .denied { state = .bluetoothDenied; return } central = CBCentralManager(delegate: self, queue: bleQueue)

text

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 384)May include surrounding context.

md
- [ ] Firmware protocol document located; every opcode, length and CRC variant traced to it
- [ ] Manifest: API 31+ permissions, legacy ones capped at `maxSdkVersion="30"`, location only if needed
- [ ] Runtime permission and Bluetooth-off states handled with a user-visible path
- [ ] `Info.plist`: `NSBluetoothAlwaysUsageDescription`; `bluetooth-central` only if background is required
- [ ] Scans use filters, a time limit and stop on match
- [ ] Every GATT operation goes through one queue with a timeout
- [ ] No callback touches UI or unsynchronised state; one serial context owns the link

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 429)May include surrounding context.

md
| Length fields bounds-checked | Missing | `FrameParser.kt:22` trusts `data[1]` |
| CRC verified on every frame | Met | `Crc16.kt`, CRC-16/CCITT-FALSE per firmware doc 2.3 |

### Manifest, Info.plist and background changes
- <permission / key / service type added or required, with store-review impact>

### Questions

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/flutter.md (reported line 35)May include surrounding context.

md
If the app derives location from scans, drop `neverForLocation`, keep `ACCESS_FINE_LOCATION` uncapped and
pass `androidUsesFineLocation: true` to `startScan`.

iOS `Info.plist`: `NSBluetoothAlwaysUsageDescription`; `UIBackgroundModes` with `bluetooth-central` only if
needed, plus `FlutterBluePlus.setOptions(restoreState: true)` before any other call.

## Runtime permissions with permission_handler

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/flutter.md (reported line 57)May include surrounding context.

md
- On Android, `permanentlyDenied` is only reported by `request()`, not by `status`. Offer `openAppSettings()`.
- iOS with CocoaPods: permission_handler needs the `PERMISSION_BLUETOOTH=1` macro in the Podfile
  `post_install` block; with Swift Package Manager the `Info.plist` key is enough. Check the plugin README
  for the exact macro name for your version.
- `DeviceInfoPlugin` is from device_info_plus; any way of reading the SDK level works.

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 BLE (CoreBluetooth central)

Load this for Swift code that uses `CBCentralManager` and `CBPeripheral`. Facts were checked against
developer.apple.com (CoreBluetooth reference, `Info.plist` keys, TN3115).

## Info.plist, capabilities and review

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 6)May include surrounding context.

md
Load this for Swift code that uses `CBCentralManager` and `CBPeripheral`. Facts were checked against
developer.apple.com (CoreBluetooth reference, `Info.plist` keys, TN3115).

## Info.plist, capabilities and review

| Key or setting | When | Notes |
|---|---|---|

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 16)May include surrounding context.

md
- Write the usage string around the user benefit ("Connect to your thermostat to change settings"),
  not "This app uses Bluetooth".
- Every new key or background mode is an `Info.plist` change with App Review impact. Call it out in the MR.
- iOS 18+: AccessorySetupKit offers a system picker for accessories with app-provided names and images.
  Consider it for new products; per TN3115, iOS 26 limits some background relaunch cases to apps that
  set up their accessories with AccessorySetupKit.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/protocol-and-dfu.md (reported line 212)May include surrounding context.

md
Bluetooth on, user consent, screen-on or foreground service for the transfer on Android.
4. Request high connection priority (Android) and the largest MTU; chunk from the negotiated size.
5. Send chunks with flow control and per-chunk ACK or windowed ACK; persist the confirmed offset.
6. On disconnect: back off, reconnect, query the offset, resume. Never restart from zero without asking
   the device.
7. After the device reboots: reconnect, rediscover services (the GATT table may change), read the version,
   and confirm success only when it matches the release.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/protocol-and-dfu.md (reported line 222)May include surrounding context.

kotlin
sealed interface DfuState {
    data object Checking : DfuState
    data class Blocked(val reason: BlockReason) : DfuState      // low battery, incompatible, no consent
    data class Transferring(val sent: Long, val total: Long) : DfuState
    data class Paused(val confirmedOffset: Long) : DfuState
    data object Validating : DfuState

Real-device DFU failure testing is instructed without a warning about firmware corruption or device recovery risks.

Medium
Category
Output Handling
Confidence
90% confidence
Finding

The release checklist instructs testing firmware updates with an interrupted connection, low battery, and an incompatible image. These tests can leave a peripheral unusable if update safeguards fail, but the document does not warn about that risk or limit testing to recoverable, non-production hardware.

Content

No source excerpt is available for this finding.