Back to skill

Security audit

Off-grid radio for sovereign AI. LoRa mesh comms via Meshtastic — no internet required.

Security checks for vulnerabilities and agentic risk

Overview

The skill fits Meshtastic messaging overall, but needs Review because it can automatically publish location/device metadata and persist or forward mesh traffic in ways the docs understate.

Install only after reviewing the code and configuration carefully. Disable map publishing in code before running, avoid sending sensitive messages or precise locations, use a private log directory with restrictive permissions, prefer group-based serial access over chmod 666, and treat all received mesh/MQTT text as untrusted external content before forwarding or acting on it.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mqtt_bridge.py:36
Finding
Location and Device Metadata Publishing Is Enabled by Default<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mqtt_bridge.py:36-47`, `scripts/mqtt_bridge.py:184-240`, `scripts/mqtt_bridge.py:340-347`, `scripts/mqtt_bridge.py:387-397` **Vulnerability Type**: Privacy-sensitive external transmission enabled without explicit consent **Risk Level**: High ### Vulnerable Code ```python # Spanish Map MQTT (publish position) MQTT_MAP_BROKER = "mqtt.meshtastic.es" MQTT_MAP_PORT = 1883 MQTT_MAP_USER = "meshdev" MQTT_MAP_PASS = "large4cats" # My location (set your coordinates) MY_LAT = 0.0 # Set your latitude MY_LON = 0.0 # Set your longitude # State MAP_ENABLED = True # Toggle via socket command ``` ```python def publish_map_report(): """Publish position to Spanish map (protobuf format)""" global mesh_interface, mqtt_map, MAP_ENABLED if not MAP_ENABLED: log.info("📍 Map report skipped (disabled)") return if not mesh_interface or not mqtt_map: log.warning("Map report skipped: no connection") return try: from meshtastic.protobuf import mqtt_pb2, mesh_pb2, portnums_pb2 my_node = mesh_interface.getMyNodeInfo() if not my_node: return pos = my_node.get('position', {}) lat, lon = pos.get('latitude'), pos.get('longitude') if not lat or not lon: log.info("Map report skipped: no GPS fix") return my_info = mesh_interface.myInfo metadata = mesh_interface.metadata user = my_node.get('user', {}) node_num = my_info.my_node_num # Fuzzy position (~2km) lat_fuzzy = round(lat * 50) / 50 lon_fuzzy = round(lon * 50) / 50 # Create MapReport protobuf map_report = mqtt_pb2.MapReport() map_report.long_name = user.get('longName', 'Unknown') map_report.short_name = user.get('shortName', '??') map_report.latitude_i = int(lat_fuzzy * 1e7) ...[truncated 3591 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Change the source default to `MAP_ENABLED = False`. 2. Parse one authoritative configuration file and enforce `mqtt_publish.enabled`. 3. Do not connect to the map broker until the user explicitly enables publishing. 4. Present the exact fields, destination broker, publication interval, and privacy implications before obtaining consent. 5. Persist the opt-in state securely so restarting the process does not silently re-enable publishing. 6. Permit users to omit node names, altitude, hardware, firmware, and gateway identifiers. 7. Allow configurable fuzzing and consider randomized or coarser location reporting rather than a stable grid point. 8. Add an integration test asserting that no map connection or publication occurs with the default configuration. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mqtt_bridge.py:29
Finding
MQTT Credentials and Sensitive Traffic Are Transmitted Without TLS<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mqtt_bridge.py:29-40`, `scripts/mqtt_bridge.py:379-392` **Vulnerability Type**: Plaintext transport and hardcoded credentials **Risk Level**: High ### Vulnerable Code ```python # Global MQTT (receive traffic) MQTT_GLOBAL_BROKER = "mqtt.meshtastic.org" MQTT_GLOBAL_PORT = 1883 MQTT_GLOBAL_USER = "meshdev" MQTT_GLOBAL_PASS = "large4cats" MQTT_GLOBAL_ROOT = "msh/EU_868/2/json" # Spanish Map MQTT (publish position) MQTT_MAP_BROKER = "mqtt.meshtastic.es" MQTT_MAP_PORT = 1883 MQTT_MAP_USER = "meshdev" MQTT_MAP_PASS = "large4cats" ``` ```python # Connect to global MQTT (receive) mqtt_global = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) mqtt_global.username_pw_set(MQTT_GLOBAL_USER, MQTT_GLOBAL_PASS) mqtt_global.on_connect = on_global_connect mqtt_global.on_message = on_global_message mqtt_global.connect(MQTT_GLOBAL_BROKER, MQTT_GLOBAL_PORT, 60) mqtt_global.loop_start() # Connect to map MQTT (publish) mqtt_map = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) mqtt_map.username_pw_set(MQTT_MAP_USER, MQTT_MAP_PASS) mqtt_map.on_connect = on_map_connect mqtt_map.connect(MQTT_MAP_BROKER, MQTT_MAP_PORT, 60) mqtt_map.loop_start() ``` ### Technical Analysis Both MQTT connections use TCP port 1883 and never configure TLS through `tls_set`, `tls_set_context`, or an equivalent mechanism. MQTT authentication values and all application data therefore travel without transport encryption or authenticated server identity. The credentials are also duplicated in source code, `CONFIG.md`, and `references/SETUP.md`. Even if these values are intended as public community credentials, plaintext transport permits an on-path actor to inspect message content, observe published locations, alter packets, or impersonate the broker through DNS or network manipulation. ### Attack Path 1. The bridge connects to either MQTT broker over port 1883. 2. An attacker obtains an on-path position, such as control of a local wireless network ...[truncated 763 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use MQTT over TLS, normally port 8883, for both brokers. 2. Configure certificate verification with the operating system trust store or a pinned broker CA. 3. Enforce hostname verification and fail closed on certificate errors. 4. Move credentials out of source and documentation into protected environment variables, a secret manager, or a configuration file with mode `0600`. 5. Use separate, least-privileged credentials for subscription and map publication. 6. Restrict broker ACLs to the exact required topics and operations. 7. Rotate any credentials that are not intentionally public. 8. Document explicitly if community credentials are public, while still protecting message integrity and confidentiality with TLS. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mqtt_bridge.py:89
Finding
Predictable Shared Temporary Files Permit Local Disclosure and Symlink Attacks<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mqtt_bridge.py:89-94`, `scripts/mqtt_bridge.py:156-165`, `scripts/mqtt_bridge.py:363-368` **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: High ### Vulnerable Code ```python if text: log.info(f"📻 RF [{sender}]: {text}") # Log to messages file with open('/tmp/mesh_messages.txt', 'a') as f: f.write(f"{datetime.utcnow().isoformat()}|RF|{sender}|local|{text}\n") ``` ```python with open('/tmp/mesh_messages.txt', 'a') as f: f.write(f"{datetime.utcnow().isoformat()}|{channel}|{sender}|{dist}|{text}\n") # Save node cache periodically if len(node_positions) % 10 == 0: try: with open('/tmp/mesh_nodes.json', 'w') as f: json.dump(node_positions, f) except: pass ``` ```python # Load cached positions try: with open('/tmp/mesh_nodes.json', 'r') as f: node_positions = json.load(f) log.info(f"Loaded {len(node_positions)} cached positions") except: pass ``` Related state files use the same pattern in `scripts/mesh_monitor.py:12-14,42-50` and `scripts/mesh_digest.py:12-13,27-35`. ### Technical Analysis The application stores messages, sender identifiers, node locations, monitoring state, and digest state at fixed names directly under the shared `/tmp` directory. Files are opened using ordinary `open()` calls without: - Explicit restrictive permissions - Ownership validation - Symlink rejection - Exclusive creation - Atomic replacement - A private parent directory A local attacker can pre-create one of these paths as a symbolic link. The bridge's use of write mode for `mesh_nodes.json` follows the link and truncates the target if the service user can write it. Append-mode logs can similarly be redirected. The resulting files may also be readable by other local users depending on the process umask and existing file permissions. ### Attack Path 1. An unprivileged local attacker predicts the fixed path `/tmp/m ...[truncated 983 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store runtime data under a private directory such as `$XDG_STATE_HOME/meshtastic` or `/var/lib/meshtastic-bridge`. 2. Create the directory with mode `0700` and verify its owner before use. 3. Create message and state files with mode `0600`. 4. Reject symbolic links using `os.open()` with `O_NOFOLLOW` where supported. 5. Verify that opened files are regular files owned by the expected service account. 6. Use atomic writes through a temporary file in the same private directory followed by `os.replace()`. 7. Set a restrictive service umask, such as `UMask=0077`, in the systemd unit. 8. Apply log size limits and rotation to prevent unbounded storage consumption. 9. If system-wide service storage is used, run under a dedicated unprivileged user with access only to the radio device and its own state directory. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/SETUP.md:63
Finding
Setup Guide Grants Every Local User Read/Write Access to the Radio Device<![CDATA[ ## Vulnerability Details **File Location**: `references/SETUP.md:63-71` **Vulnerability Type**: Excessive device permissions **Risk Level**: High ### Vulnerable Code ```bash # Ensure user is in `dialout` group: `sudo usermod -a -G dialout $USER` **Permission denied:** ```bash sudo chmod 666 /dev/ttyACM0 # Or add udev rule for permanent fix ``` ``` ### Technical Analysis Mode `0666` grants read and write access to the serial device to every local account. Access to the Meshtastic serial interface is security-sensitive because it permits device commands, message transmission, configuration access, and denial of service through exclusive device locking. This permission is broader than necessary. The guide already identifies the safer `dialout` group approach, which should be the only general recommendation. A dedicated service group or narrowly scoped udev rule would further limit access. ### Attack Path 1. An administrator follows the troubleshooting instruction and runs `sudo chmod 666 /dev/ttyACM0`. 2. Any untrusted local account opens the serial port. 3. The account communicates directly with the Meshtastic device, transmits unauthorized messages, reads available data, changes configuration, or holds the port open. 4. The legitimate bridge can no longer reliably access the device because serial access may be exclusive. ### Impact Assessment Any local user can gain the same serial-device access needed by the bridge. This can allow unauthorized radio transmissions, disclosure of device and network information, radio reconfiguration, disruption of the bridge, and possible reboot or reset operations supported by the device protocol. It does not directly grant root privileges, but it breaks the intended local access-control boundary. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `sudo chmod 666 /dev/ttyACM0` recommendation. 2. Add only the intended user or dedicated service account to the `dialout` group. 3. Prefer a dedicated `meshtastic` group if access to all serial devices through `dialout` is unnecessary. 4. Supply a vendor/product-specific udev rule that assigns the device to the dedicated group with mode `0660`. 5. Run the bridge as a dedicated unprivileged service user belonging only to the required device group. 6. Document that group membership changes normally require logging out and back in. 7. Include a validation command such as `stat /dev/ttyACM0` so users can verify that the device is not world-accessible. ]]>

T08 · Insecure Dependencies

Warning
Location
references/SETUP.md:27
Finding
Installation Uses Unpinned Third-Party Dependencies Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `references/SETUP.md:27-38` **Vulnerability Type**: Mutable dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash # Create Python virtual environment python3 -m venv venv source venv/bin/activate # Install required packages pip install meshtastic paho-mqtt # For development/debugging pip install bleak # BLE support (optional) ``` The README additionally recommends: ```bash pip install meshtastic paho-mqtt pip install mcp # optional, for MCP integration ``` ### Technical Analysis The installation instructions request packages by name without exact versions, hashes, a lockfile, or a constraints file. A future installation can therefore resolve to dependency versions that differ from those reviewed with this Skill. Package installation also executes packaging and build logic under the installing user's account. No typo-squatted dependency name or known malicious package was identified in the audited files. The risk arises from mutable dependency resolution and lack of integrity controls rather than evidence that the named packages are currently malicious. ### Attack Path 1. A user follows the documented `pip install` commands. 2. Pip resolves the latest available versions and transitive dependencies at installation time. 3. A compromised release, compromised publisher account, malicious transitive dependency, or unexpected incompatible update is downloaded. 4. Packaging or runtime code executes with the privileges of the user or service environment. 5. Because the bridge handles serial hardware, message logs, and network communication, a compromised dependency inherits access to those resources. ### Impact Assessment A compromised dependency can execute arbitrary code as the account performing installation or running the bridge. Under the recommended service configuration this should be a normal user, but that user has access to the serial radio, message history, network conne ...[truncated 107 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Publish a reviewed `requirements.txt` or lockfile with exact versions. 2. Include cryptographic hashes and install with `pip install --require-hashes -r requirements.txt`. 3. Pin transitive dependencies, not only direct dependencies. 4. Use a controlled package index or documented trusted source. 5. Add automated dependency scanning and periodic review before updating pins. 6. Install into a dedicated virtual environment as an unprivileged user. 7. Separate optional development dependencies such as BLE support from production requirements. 8. Record supported Python and dependency versions so users can reproduce the audited environment. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mqtt_bridge.py:113
Finding
Attacker-Controlled Mesh Messages Can Become Indirect Agent Instructions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mqtt_bridge.py:113-166`, `scripts/mcp_server.py:322-334`, `SKILL.md:117-148` **Vulnerability Type**: Indirect prompt injection through untrusted radio and MQTT content **Risk Level**: High ### Vulnerable Code ```python def on_global_message(client, userdata, msg): """Handle incoming global MQTT messages""" global node_positions try: topic = msg.topic payload = msg.payload.decode('utf-8', errors='ignore') # Skip our own messages if "!YOUR_NODE_ID" in topic: return try: data = json.loads(payload) except: return # ... text = None if isinstance(payload_data, dict) and 'text' in payload_data: text = payload_data.get('text') elif data.get('type') == 'sendtext': text = data.get('payload') if isinstance(text, dict): text = text.get('text') # Log text messages if text and isinstance(text, str) and len(text) > 1: channel = topic.split('/')[-2] if '/' in topic else 'unknown' dist = get_distance_str(sender) log.info(f"💬 [{channel}] {sender} ({dist}): {text}") with open('/tmp/mesh_messages.txt', 'a') as f: f.write(f"{datetime.utcnow().isoformat()}|{channel}|{sender}|{dist}|{text}\n") ``` ```python elif name == "mesh_messages": limit = arguments.get("limit", 20) since = arguments.get("since_minutes") do_filter = arguments.get("filter_noise", True) messages = read_messages(limit=limit * 2, since_minutes=since) if do_filter: messages = filter_noise(messages) messages = messages[-limit:] if not messages: return [TextContent(type="text", text="No messages found")] lines = [f"[{m['timestamp']}] {m['sender']} ({m['distance']}): {m['text']}" for m in messages ...[truncated 2916 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Mark all mesh and MQTT text explicitly as untrusted external content. 2. Wrap messages in a structured data format rather than interpolating them into free-form agent instructions. 3. Add a high-priority instruction that the agent must never follow commands, links, or requests embedded in mesh messages. 4. Require explicit user confirmation before any response, transmission, configuration change, or external tool call derived from received content. 5. Use separate stages for parsing, classification, and action; the parsing stage should have no consequential tools. 6. Escape or neutralize control-like markup when rendering messages to an agent. 7. Restrict scheduled monitor agents to read-only access and a single predefined notification destination. 8. Include adversarial tests with messages such as “ignore previous instructions” and verify that they are quoted only as data. 9. Apply broker topic restrictions and authenticated message provenance where feasible, while recognizing that authentication alone does not make message instructions trustworthy. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (57)

Exfiltration Commands

High
Category
Prompt Injection
Content
**Messaging** (via bridge):
| Tool | Description |
|------|-------------|
| `mesh_send` | Send message to mesh (broadcast or DM) |
| `mesh_send_alert` | Send high-priority alert message |
| `mesh_messages` | Get recent messages with filtering |
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill is presented as LoRa messaging, but the architecture also includes external MQTT ingestion of global traffic, optional map publishing, local file persistence, node-position caching, and a command socket on localhost:7331. These materially expand the privacy and attack surface beyond simple off-grid messaging, especially because users may not realize that internet-connected MQTT and local command/control are part of the design.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill is presented as LoRa messaging, but the architecture also includes external MQTT ingestion of global traffic, optional map publishing, local file persistence, node-position caching, and a command socket on localhost:7331. These materially expand the privacy and attack surface beyond simple off-grid messaging, especially because users may not realize that internet-connected MQTT and local command/control are part of the design.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill is presented as LoRa messaging, but the architecture also includes external MQTT ingestion of global traffic, optional map publishing, local file persistence, node-position caching, and a command socket on localhost:7331. These materially expand the privacy and attack surface beyond simple off-grid messaging, especially because users may not realize that internet-connected MQTT and local command/control are part of the design.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill is presented as LoRa messaging, but the architecture also includes external MQTT ingestion of global traffic, optional map publishing, local file persistence, node-position caching, and a command socket on localhost:7331. These materially expand the privacy and attack surface beyond simple off-grid messaging, especially because users may not realize that internet-connected MQTT and local command/control are part of the design.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Permission denied:**
```bash
sudo chmod 666 /dev/ttyACM0
# Or add udev rule for permanent fix
```
Confidence
99% confidence
Finding
The instruction to use chmod 666 is an unsafe parameter choice for a privileged tool because it grants universal read/write access to a hardware device. This is dangerous because it turns a permission issue into a broad local compromise of device control rather than solving access with least privilege.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The configuration enables receipt of global Meshtastic MQTT traffic by default and includes real broker credentials, but it does not clearly warn that this may ingest third-party mesh messages and associated metadata. In a messaging skill, this creates a meaningful privacy and compliance risk because operators may unknowingly collect or process non-local communications.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The alert forwarding section allows mesh-derived message content or metadata to be sent to third-party services such as Telegram or Discord without an explicit warning about external disclosure. In this skill's context, forwarding radio network data off-device can expand exposure beyond the local mesh and surprise users who expect communications to remain confined to their node or network.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README prominently advertises global MQTT traffic and local logging to `/tmp/mesh_messages.txt` without an equally explicit warning that messages may be publicly relayed and stored in a world-readable or ephemeral location depending on host configuration. In a messaging skill, this can lead users or downstream agents to handle sensitive data under false assumptions of privacy, causing inadvertent data exposure.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill describes shell commands, file access, temp-file logging, and local service control, but it declares no explicit tool scope or permission boundaries. In an agent environment, this under-specification can cause the skill to be invoked with broader host access than users expect, increasing the chance of unintended file reads/writes or command execution.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The monitoring examples instruct the agent to read mesh messages, summarize them, translate them, and deliver alerts over external channels such as Telegram, but the warning about privacy exposure is limited and not tied directly to forwarding content off-device. That can result in sensitive radio traffic, identifiers, or inferred location information being redistributed to third-party services without clear user acknowledgement.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Try different USB cable (must be data cable)
- Try different USB port
- Check `dmesg | tail -20` for errors
- Ensure user is in `dialout` group: `sudo usermod -a -G dialout $USER`

**Permission denied:**
```bash
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Try different USB cable (must be data cable)
- Try different USB port
- Check `dmesg | tail -20` for errors
- Ensure user is in `dialout` group: `sudo usermod -a -G dialout $USER`

**Permission denied:**
```bash
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Try different USB cable (must be data cable)
- Try different USB port
- Check `dmesg | tail -20` for errors
- Ensure user is in `dialout` group: `sudo usermod -a -G dialout $USER`

**Permission denied:**
```bash
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Try different USB cable (must be data cable)
- Try different USB port
- Check `dmesg | tail -20` for errors
- Ensure user is in `dialout` group: `sudo usermod -a -G dialout $USER`

**Permission denied:**
```bash
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Try different USB cable (must be data cable)
- Try different USB port
- Check `dmesg | tail -20` for errors
- Ensure user is in `dialout` group: `sudo usermod -a -G dialout $USER`

**Permission denied:**
```bash
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Try different USB cable (must be data cable)
- Try different USB port
- Check `dmesg | tail -20` for errors
- Ensure user is in `dialout` group: `sudo usermod -a -G dialout $USER`

**Permission denied:**
```bash
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Static analysis

No suspicious patterns detected.