Back to skill

Security audit

Terminal

Security checks for vulnerabilities and agentic risk

Overview

This local terminal helper matches its stated purpose, but its safety promises are stronger than the code actually enforces.

Install only if you are comfortable with a skill that can run arbitrary local shell commands and keep local command/output history. Use preview and --no-store-output for sensitive work, and do not rely on its destructive-command confirmation or token redaction as a complete safety boundary.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib/safety.py:4
Finding

Shell Safety Controls Are Bypassable Through Separators and Alternate Executable Paths

Content
View full analysis
\s*\S', r'>>\s*\S', ] def risk_level(command: str) -> str: cmd = command.strip() for pattern in HIGH_RISK_PATTERNS: if re.search(pattern, cmd): return "high" return "normal" def requires_confirmation(command: str) -> bool: return risk_level(command) == "high" ``` The resulting classification controls execution in `scripts/run_command.py`: ```python if requires_confirmation(args.command) and not args.yes: message = "Blocked: high-risk command requires explicit confirmation with --yes" print(message) print(f"Risk level: {risk}") append_history( args.command, args.cwd, risk, 2, "", message, "blocked", store_output=not args.no_store_output ) sys.exit(2) try: completed = subprocess.run( args.command, shell=True, cwd=args.cwd, text=True, capture_output=True ) ``` ### Technical Analysis The Skill accepts arbitrar ...[truncated 2934 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_command.py:14
Finding

Sensitive Command Output Is Persisted by Default with Incomplete Redaction

Content
View full analysis
str: result = text or "" for pattern, replacement in SENSITIVE_PATTERNS: result = re.sub(pattern, replacement, result) return result ``` ### Technical Analysis Command text, the absolute working directory, stdout, and stderr are wri ...[truncated 3051 chars]
Remediation
View remediation
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 (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims strong safety properties and operational features such as preview-first execution, destructive-command confirmation, privacy-aware history controls, and risk detection, but the analysis indicates those controls are not actually implemented. This is dangerous because users and downstream agents may trust nonexistent safeguards and invoke the skill in risky contexts, leading to command execution, data loss, or exposure without the promised protections.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This is a true tool-parameter-abuse issue because the core tool parameter --command is passed directly into subprocess.run with shell=True. The skill context makes this more dangerous, not less: the tool is explicitly designed to translate natural language into terminal actions, so a prompt-influenced or attacker-supplied command can cause arbitrary local execution, file modification, data exfiltration, or destructive operations if the confirmation logic is bypassed, incomplete, or misclassified.

Content

Scanner excerpt · scripts/run_command.py (reported line 84)May include surrounding context.

python
sys.exit(2)

    try:
        completed = subprocess.run(
            args.command,
            shell=True,
            cwd=args.cwd,

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill advertises shell, file read, and file write capabilities but does not declare an explicit tool scope such as permissions or allowed-tools. That creates an authorization ambiguity where a reviewer or enforcement layer may not be able to reliably constrain what the skill is allowed to do, increasing the chance of over-broad execution or unintended access.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The invocation text is very broad, covering many common user intents, which can cause the skill to be selected in situations beyond narrowly scoped terminal assistance. In a shell-capable skill, over-triggering increases the chance that powerful local execution features are brought into contexts where they are unnecessary or insufficiently reviewed.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The script executes a user-supplied string with subprocess.run(..., shell=True), which hands the command to the system shell for parsing and execution. In a shell-copilot skill this is especially dangerous because any untrusted or incorrectly constructed input can trigger shell metacharacter expansion, chaining, redirection, or command substitution, leading to arbitrary command execution beyond the intended action.

Content

Scanner excerpt · scripts/run_command.py (reported line 84)May include surrounding context.

python
sys.exit(2)

    try:
        completed = subprocess.run(
            args.command,
            shell=True,
            cwd=args.cwd,

Static analysis

No suspicious patterns detected.