Back to skill

Security audit

Hackrf Sdr

Security checks for vulnerabilities and agentic risk

Overview

This HackRF skill mostly does what it says, but its broad radio monitoring/demodulation scope lacks legal/privacy guardrails and one capture path uses unsafe shared temporary files.

Review before installing. Use this only for lawful, authorized SDR work, avoid demodulating or recording third-party communications without permission, and prefer running it in a controlled single-user environment. The publisher should add explicit legal/privacy guardrails and replace fixed /tmp capture paths with private temporary directories.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/waterfall.py:410
Finding

Predictable Shared Temporary File Enables Symlink-Based File Overwrite

Content
View full analysis

Vulnerability Details

File Location: scripts/waterfall.py, lines 410–438
Vulnerability Type: Predictable and insecure temporary file handling
Risk Level: Medium

Vulnerable Code

python
n_samples = int(sample_rate * args.duration)
iq_file = '/tmp/iq_waterfall_capture.raw'
print(f"Capturing IQ: center={center_freq/1e6:.1f} MHz, "
      f"rate={sample_rate/1e6:.1f} MSPS, "
      f"duration={args.duration}s")
result = subprocess.run(
    ['hackrf_transfer', '-f', str(int(center_freq)),
     '-s', str(int(sample_rate)),
     '-l', str(args.lna), '-g', str(args.vga),
     '-n', str(n_samples), '-r', iq_file],
    capture_output=True, text=True, timeout=300)
if result.returncode != 0:
    print(f"ERROR: hackrf_transfer failed: {result.stderr}")
    sys.exit(1)
freq = center_freq
rate = sample_rate

# ...

if not args.input and iq_file.startswith('/tmp/'):
    try:
        os.remove(iq_file)
    except OSError:
        pass

Technical Analysis

The script stores automatically captured IQ data at the fixed, globally predictable path /tmp/iq_waterfall_capture.raw. It neither creates a private temporary directory nor safely reserves and validates the output file before passing its path to hackrf_transfer.

On a multi-user system, another local user can pre-create this path as a symbolic link to a file writable by the victim. If hackrf_transfer follows the link when opening its output, the linked target may be overwritten or corrupted with IQ data. The same fixed path also creates race conditions between concurrent instances: one process can overwrite, consume, or delete another process's capture.

Arguments are passed to subprocess.run as a list without shell=True, so this is not command injection. The issue is specifically unsafe temporary-file handling and a time-of-check/time-of-use exposure involving an external writer.

Attack Path

  1. A local attacker determines that the script always uses `/tmp/iq_waterfall_capture.r ...[truncated 1422 chars]
Remediation
View remediation

Remediation Suggestions

  • Create a unique, mode-0700 temporary directory using tempfile.TemporaryDirectory() and place the capture inside it.
  • Keep the temporary-directory object alive until capture processing is complete, and use a try/finally block or context manager to guarantee cleanup.
  • Avoid a shared deterministic filename in /tmp.
  • Before invoking the external writer, verify that the parent directory is private and that the destination is not a symbolic link.
  • If supported by hackrf_transfer, write through an already-secured file descriptor or use an option that refuses to follow symbolic links.
  • Prevent concurrent runs from sharing output state.

Example hardening pattern:

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory(prefix='hackrf-waterfall-') as temp_dir:
    iq_file = str(Path(temp_dir) / 'capture.raw')

    result = subprocess.run(
        ['hackrf_transfer', '-f', str(int(center_freq)),
         '-s', str(int(sample_rate)),
         '-l', str(args.lna), '-g', str(args.vga),
         '-n', str(n_samples), '-r', iq_file],
        capture_output=True,
        text=True,
        timeout=300,
        check=False,
    )

    if result.returncode != 0:
        raise RuntimeError(
            f"hackrf_transfer failed: {result.stderr}"
        )

    generate_iq_waterfall(
        iq_file, center_freq, sample_rate, args.outdir,
        title, fft_size=args.fft, avg_factor=args.avg
    )
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
94% confidence
Finding

The description overstates the scope of the skill. The supplied code supports frequency-range scanning via HackRF, IQ acquisition, basic signal analysis (FFT/spectrogram, noise floor, SNR, peak grouping), and waterfall/spectrum plot generation, which aligns with part of the declaration. However, there is no implementation for demodulating FM/AM/SSB or identifying modulation types, both of which are explicitly claimed. The code’s primary purpose is a focused waterfall/spectrum visualization and scan-report tool, not a comprehensive SDR analysis and demodulation skill. No suspicious unrelated resource access or off-purpose behavior is evident beyond invoking HackRF command-line tools and writing an output image.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

After analysis, delete IQ capture files:

bash
rm -f /tmp/iq_capture.raw

Tips

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs use of shell commands plus file reads/writes but does not declare any tool scope or permissions boundaries. In an agent environment, that increases the chance the skill is invoked with broader-than-expected capabilities, enabling command execution and file operations without explicit least-privilege constraints.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger language is broad enough to invoke the skill for generic radio monitoring or signal-intelligence tasks, including potentially sensitive surveillance contexts. Overbroad activation can cause an agent to select this skill in situations involving legal, privacy, or policy-sensitive requests without sufficient user confirmation or safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill provides concrete instructions for capturing and demodulating radio signals but omits any warning about legal restrictions, consent, or privacy implications. That omission makes misuse more likely, especially because SDR workflows can intercept sensitive communications depending on jurisdiction and band.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/waterfall.py (reported line 416)May include surrounding context.

python
print(f"Capturing IQ: center={center_freq/1e6:.1f} MHz, "
                  f"rate={sample_rate/1e6:.1f} MSPS, "
                  f"duration={args.duration}s")
            result = subprocess.run(
                ['hackrf_transfer', '-f', str(int(center_freq)),
                 '-s', str(int(sample_rate)),
                 '-l', str(args.lna), '-g', str(args.vga),

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/waterfall.py (reported line 447)May include surrounding context.

python
else:
            print(f"Running hackrf_sweep: {args.start}-{args.end} MHz, "
                  f"{args.sweeps} sweeps, LNA={args.lna} VGA={args.vga}...")
            result = subprocess.run(
                ['hackrf_sweep', '-f',
                 f'{int(args.start)}:{int(args.end)}',
                 '-l', str(args.lna), '-g', str(args.vga),

Static analysis

No suspicious patterns detected.