Back to skill

Security audit

ESP-IDF Helper

Security checks for vulnerabilities and agentic risk

Overview

The skill is openly for ESP-IDF flashing and packaging, but its helper scripts have unsafe input and path handling that could run unintended commands or include unintended local files.

Install only if you trust the source and are comfortable reviewing or fixing the helper scripts first. Avoid using this with untrusted build directories or flash_args files, avoid the permanent bashrc PATH change unless necessary, and do not run usbipd or flashing workflows with elevated privileges unless you have verified the exact commands and target devices.

Vulnerability Patterns
  • 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
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/capture_idf_help.sh:14
Finding

Shell Command Injection Through IDF_PATH

Content
View full analysis
/dev/null; idf.py --help" > "$OUT_REL" elif command -v idf.py >/dev/null 2>&1; then idf.py --help > "$OUT_REL" fi ``` ### Technical Analysis `IDF_PATH` is copied into `ESPIDF_ROOT` and then interpolated into a command string passed to `bash -lc`. Although double quotes are added around the intended path, embedded quotes, command substitutions, shell operators, or other shell syntax in the environment-variable value can escape the intended `source` argument. The preliminary `-f "$ESPIDF_ROOT/export.sh"` check does not make interpolation into a second shell safe. A specially named directory can satisfy the file check while its path remains syntactically dangerous when incorporated into the nested command string. ### Attack Path 1. An attacker influences the `IDF_PATH` environment variable or persuades the user to configure ESP-IDF under a specially crafted directory name. 2. The crafted directory contains an `export.sh` file, allowing the file-existence check to pass. 3. The user executes `scripts/capture_idf_help.sh`. 4. The path is embedded into the argument supplied to `bash -lc`. 5. The nested shell parses attacker-controlled syntax as commands rather than treating the entire value as a literal path. 6. Those commands execute with the privileges of the user running the script. ### Impact Assessment Successful exploitation provides arbitrary local command execution under the invoking user's account. The attacker could read or modify files accessible to that user, alter source code or firmware artifacts, tamper with the generated reference file, or execute additional locally available programs. If the scr ...[truncated 92 chars]
Remediation
View remediation
/dev/null idf.py --help > "$OUT_REL" elif command -v idf.py >/dev/null 2>&1; then idf.py --help > "$OUT_REL" else echo "ERROR: idf.py not found." >&2 exit 1 fi ``` Additionally: 1. Canonicalize `IDF_PATH` with `realpath`. 2. Require `export.sh` to be a regular file in an expected, trusted ESP-IDF checkout. 3. Reject paths containing control characters. 4. Avoid evaluating any environment-derived value as shell source code. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/usbipd_attach_serial.sh:134
Finding

PowerShell Command Injection Through BUSID and DISTRO Arguments

Content
View full analysis
&1) local bind_rc=$? set -e # ... set +e local attach_out attach_out=$(powershell.exe -NoProfile -Command "$cmd" 2>&1) local attach_rc=$? set -e } ``` ### Technical Analysis The values accepted through `--busid` and `--distro` are concatenated directly into PowerShell command text. The resulting strings are passed to `powershell.exe -Command`, which parses them as PowerShell source code. Bash quoting protects the value only while Bash constructs the argument. It does not prevent PowerShell from interpreting separators, expressions, quoting characters, or other PowerShell syntax contained in that argument. Neither value is validated against the expected syntax before execution. Values extracted from `usbipd list` also cross a command-interpreter boundary and should not be assumed safe solely because they originated from command output. ### Attack Path 1. An attacker supplies a malicious `--busid` or `--distro` value, directly or through an untrusted wrapper invoking the script. 2. The script appends that value to `bind_cmd` or `cmd`. 3. The complete string is passed to `powershell.exe -Command`. 4. PowerShell parses the attacker-controlled portion as command syntax ...[truncated 632 chars]
Remediation
View remediation
&2 return 2 fi ``` 2. Obtain valid WSL distribution names from `wsl.exe --list --quiet` and require an exact match. 3. Do not concatenate arguments into a PowerShell program string. 4. Pass untrusted values as positional arguments to a fixed PowerShell script block and invoke the target executable with PowerShell's argument operator. 5. Add `-NonInteractive` and use an explicit executable path where practical. 6. Revalidate bus IDs parsed from `usbipd list` before processing them. 7. Keep binding and attachment operations unprivileged whenever possible and clearly separate any action that truly requires elevation. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pack_firmware.sh:39
Finding

Generated Firmware Flash Script Injection via flash_args

Content
View full analysis
"${LOG_FILE}" 2>&1; then ``` ```batch set "FLASH_PARAMS=${FLASH_PARAMS}" "%ESPTOOL%" --chip %CHIP% -p %PORT% -b %BAUD% --before=default_reset --after=no_reset --no-stub write_flash %FLASH_PARAMS%${WIN_FIRMWARE_ARGS} ``` ### Technical Analysis The project-controlled `flash_args` file is treated as trusted script source. Its first line, address fields, and filename fields are inserted into Bash and Windows batch scripts without syntax validation or interpreter-specific escaping. A crafted field can contain shell or batch metacharacters, quotes, variable-expansion syntax, command separators, or control characters. Those characters become part of the generated executable scripts. The scripts are then included in a distributable firmware ZIP and are expected to be executed by production operators. This creates a supply-chain execution path: the dangerous code is not necessarily executed while packaging, but is embedded into apparently legitimate flashing utilities and executes later on another machine. ### Attack Path 1. An ...[truncated 1025 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pack_firmware.sh:311
Finding

Arbitrary File Inclusion in Firmware Package Through Path Traversal

Content
View full analysis
Remediation
View remediation
&2 exit 1 } case "$candidate" in "$build_root"/*) ;; *) echo "ERROR: Firmware path escapes build directory: $file" >&2 exit 1 ;; esac ``` Also: 1. Reject absolute paths and any input containing `..` before resolution. 2. Decide whether symbolic links are allowed; if not, explicitly reject them. 3. Permit only expected firmware extensions and filename patterns. 4. Detect destination basename collisions. 5. Stop packaging on invalid or missing firmware files instead of continuing with warnings. 6. Build the archive from a newly created private staging directory containing only explicitly validated files. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pack_firmware.sh:69
Finding

Predictable Temporary Log Files Enable Symlink-Based File Overwrite

Content
View full analysis
"${MAC_LOG}" 2>&1; then echo "[${DEVICE_NAME}] Warning: failed to read MAC" >&2 return 1 fi } ``` ```bash flash_single() { local PORT=$1 local DEVICE_NAME=$(basename "$PORT") echo "[${DEVICE_NAME}] Flashing..." if [ ! -e "${PORT}" ]; then echo "[${DEVICE_NAME}] ERROR: Port not found: ${PORT}" return 1 fi local LOG_FILE="/tmp/flash_${DEVICE_NAME}.log" local RETRY=0 local MAX_RETRY=3 ``` Later, output redirection writes to the predictable log path: ```bash > "${LOG_FILE}" 2>&1 ``` ### Technical Analysis The generated script creates log filenames deterministically from the serial device basename. Shared temporary directories such as `/tmp` are writable by other local users. An attacker can predict names such as `flash_ttyUSB0.log` and pre-create those paths as symbolic links to files writable by the victim. When the flashing script redirects command output, the shell follows the symbolic link and opens the target for truncation and writing. The script neither creates the file atomically nor verifies file ownership and type. Parallel operations may also reuse predictable names, increasing collision and log-integrity risks. ### Attack Path 1. A local attacker determines the likely serial-port name used by the operator. 2. The attacker creates the corresponding predictable path in `/tmp` as a symbolic link to a file writable by the operator. 3. The operator runs the generated `f ...[truncated 573 chars]
Remediation
View remediation
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose is development/build/debug help, but the content also describes packaging redistributable firmware, generating standalone flashing scripts, recording MAC addresses, and bundling executables. That broader behavior materially increases supply-chain, privacy, and operational risk because users and reviewers may not expect production-line distribution and device-data collection from this skill.

Content

No source excerpt is available for this finding.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

oting: powershell.exe not found

If you encounter powershell.exe: command not found, the Windows paths are not in your PATH environment variable.

Quick Fix (current session only):

bash
export PATH="$PATH:/mnt/c/Windows/System32:/mnt/c/Windows/System32/WindowsPowerShell/v1.0"
~/skills/esp-idf-helper/scripts/usbipd_attach_serial.sh --list

Permanent Fix (add to ~/.bashrc):

bash
echo 'export PATH="$PATH:/mnt/c/Windows/System32:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Windows/SysWOW64"' >> ~/.bashrc
source ~/.bashrc

Firmware Packaging

Pack ESP-IDF build output into a distributable firmware package with cross-platform flash scripts.

Usage

bash
scripts/pack_firmware.sh <build_directory>

Example

bash
# After building your project
idf.py build

# Create firmware package
scripts/pack_firmware.sh ./build

# Output: build/firmware_package/ and build/esp_firmware_YYYYMMDD_HHMMSS.zip

Generated Package Contents

| File | Descript

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill clearly instructs shell-command usage and references local scripts, but it does not declare any explicit tool scope or allowed-tools boundary. That weakens sandboxing and reviewability, making it easier for an agent to execute shell actions beyond the user's expected ESP-IDF workflow.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill instructs users to append to ~/.bashrc, creating persistent environment changes across future sessions. Persistence is security-relevant because it alters execution behavior long-term and could normalize PATH-based trust in Windows binaries from WSL, increasing exposure if those paths or binaries are abused later.

Content

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

~/skills/esp-idf-helper/scripts/usbipd_attach_serial.sh --list

text

**Permanent Fix (add to ~/.bashrc):**
```bash
echo 'export PATH="$PATH:/mnt/c/Windows/System32:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Windows/SysWOW64"' >> ~/.bashrc
source ~/.bashrc

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This help text states that commands not recognized by idf.py will be attempted as build system targets. In a plain-text reference file, that creates an ambiguous and overly broad trigger scope because it does not clearly constrain what inputs should or should not activate this behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The help text includes commands such as "erase-flash", "erase-otadata", "clean", and "fullclean" that delete flash contents or build artifacts, but it does not warn that these actions may be destructive or irreversible. For markdown and similar user-facing documentation, safety-affecting behavior should be disclosed clearly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This script generates flash.sh and flash_one.bat that execute write_flash, which overwrites device firmware and is a destructive operation. Although the generated scripts print progress messages, the included README.txt only shows usage examples and does not warn users that running these commands will reflash attached devices and may affect device state or data.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.