Back to skill

Security audit

sshexec

Security checks for vulnerabilities and agentic risk

Overview

The skill does run SSH commands as advertised, but it needs review because it combines arbitrary remote command execution with unsafe SSH and credential-handling defaults.

Review this before installing. Use it only with explicit user-approved commands, least-privilege SSH accounts, verified host keys, and non-sensitive output. Prefer --strict-host-key, avoid putting passwords or key passphrases on the command line, and assume command logs may expose secrets or operational data.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
ssh_exec.py:69
Finding
SSH Host-Key Verification Is Disabled by Default## Vulnerability Details **File Location**: `ssh_exec.py`, lines 69-75 **Vulnerability Type**: Improper SSH server authentication **Risk Level**: High ### Vulnerable Code ```python strict_host_key: bool = False, pty: bool = False, ) -> int: """Connect and execute a single command, returning the remote exit status.""" client = paramiko.SSHClient() if strict_host_key: client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.RejectPolicy()) else: client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ``` ### Technical Analysis The `strict_host_key` option defaults to `False`. In this default mode, Paramiko's `AutoAddPolicy` automatically trusts a previously unknown SSH host key rather than rejecting it or asking the operator to verify its fingerprint. SSH host-key verification is the mechanism that authenticates the remote server. Disabling it makes the connection susceptible to a man-in-the-middle attack, particularly during the first connection or whenever no trusted key for the destination is available. Encryption alone does not prevent this attack because the client may establish the encrypted session directly with an attacker-controlled SSH server. ### Attack Path 1. A user invokes the Skill without the optional `--strict-host-key` argument. 2. The attacker obtains a network position that permits interception or redirection of traffic to the requested SSH destination, such as through DNS poisoning, routing manipulation, or a hostile local network. 3. The attacker presents an arbitrary SSH host key. 4. `AutoAddPolicy` accepts that key without validating it against a trusted fingerprint. 5. The client establishes a session with the attacker's server and submits the configured authentication and command data. 6. Depending on the authentication protocol and attacker setup, the attacker can impersonate the server, capture password credentials, ...[truncated 693 chars]
Remediation
## Remediation Suggestions - Make strict host-key verification the default behavior. - Load system or application-specific `known_hosts` entries and use `paramiko.RejectPolicy()` for unknown keys. - Support explicit host-key or fingerprint pinning for automated environments. - If an insecure compatibility mode is indispensable, require an explicit argument such as `--insecure-accept-unknown-host-key` and emit a prominent warning. - Do not silently modify trusted host-key data during normal execution. - Document a secure onboarding process through which operators verify a server fingerprint over an independent trusted channel before connecting. - Add tests confirming that unknown and changed host keys are rejected by default.

T09 · Insecure Skill Coding Practices

Warning
Location
ssh_exec.py:127
Finding
SSH Passwords and Private-Key Passphrases Are Accepted Through Process Arguments## Vulnerability Details **File Location**: `ssh_exec.py`, lines 127-130 **Vulnerability Type**: Sensitive information exposure through command-line arguments **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument("--port", type=int, default=22, help="SSH port (default: 22)") parser.add_argument("--password", help="Password for authentication") parser.add_argument("--key", dest="key_path", help="Path to private key file") parser.add_argument("--key-passphrase", dest="key_passphrase", help="Passphrase for the private key, if needed") ``` The documented usage also encourages this pattern in `SKILL.md`, lines 19-25: ```bash python3 skills/sshexec/ssh_exec.py --host "remote-server.com" --user "username" --password "password" --command "ls -la" ``` ### Technical Analysis Secrets passed as command-line arguments may be retained in shell history and exposed through process metadata, execution telemetry, audit facilities, CI/CD logs, wrapper scripts, or diagnostic output. Depending on operating-system process isolation settings, another local account may also be able to inspect the process argument vector while the command is running. Both reusable SSH passwords and private-key passphrases are affected. The documentation explicitly demonstrates supplying a password literally on the command line, increasing the likelihood that users will adopt the unsafe pattern. ### Attack Path 1. A user follows the documented example or supplies `--password` or `--key-passphrase` directly. 2. The shell stores the complete command in history, or a process monitor, job runner, audit service, or CI system records the argument vector. 3. A local user, administrator, log reader, monitoring integration, or party with access to the resulting history or telemetry retrieves the secret. 4. The attacker reuses the password to authenticate to the remote account, or uses the passphrase together with access to the associated priv ...[truncated 705 chars]
Remediation
## Remediation Suggestions - Remove or deprecate direct command-line password and passphrase arguments. - Prompt interactively with Python's `getpass.getpass()` when a password or key passphrase is needed. - For noninteractive use, accept secrets through a protected file descriptor, operating-system credential facility, or established secret-management service. - If environment-variable support is provided for compatibility, document that environment variables can also leak through logs, crash reports, and process environments; a dedicated secret channel is preferable. - Ensure secret values are never included in logs or exception messages. - Replace the literal-password example in `SKILL.md` with secure interactive or secret-manager-based usage. - Clear references to secrets as soon as practical, while recognizing that Python cannot guarantee complete in-memory erasure.

T08 · Insecure Dependencies

Note
Location
ssh_exec.py:16
Finding
Runtime Instructions Recommend Installing an Unpinned Dependency## Vulnerability Details **File Location**: `ssh_exec.py`, lines 16-22 **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Low ### Vulnerable Code ```python try: import paramiko except ImportError as exc: # pragma: no cover - dependency check sys.stderr.write( "Missing dependency 'paramiko'. Install with `pip install paramiko` before running.\n" ) raise SystemExit(1) from exc ``` ### Technical Analysis The error message directs users to install `paramiko` without a version constraint, lock file, or integrity hash. Consequently, the resolved package and its transitive dependencies can change after this project has been reviewed. The package name is legitimate and the code does not configure an untrusted package index, so there is no evidence of dependency confusion, typosquatting, or deliberate malicious-package installation in the audited files. The risk is that users following the instruction may install an unreviewed future release or retrieve packages from a locally configured, compromised, or otherwise untrusted index. ### Attack Path 1. Paramiko is absent from the runtime environment. 2. The script instructs the user to execute `pip install paramiko`. 3. `pip` resolves the current package and transitive dependency versions from its configured indexes because no reviewed versions or hashes are specified. 4. If an index, account, release, or dependency has been compromised, malicious package code may execute during installation or later import. 5. That code runs with the privileges of the user performing the installation or invoking the script. This path requires a compromised or untrusted package source or package release; the audited project does not itself supply such a package. ### Impact Assessment If the dependency supply chain is compromised, arbitrary code could execute in the installation or runtime environment with the privileges of ...[truncated 339 chars]
Remediation
## Remediation Suggestions - Declare Paramiko and all required dependencies in a maintained dependency manifest. - Pin reviewed versions or use compatible constraints backed by a lock file. - Use cryptographic hashes for deployment artifacts, such as pip's `--require-hashes` workflow. - Install dependencies from an explicitly trusted package index in an isolated virtual environment. - Incorporate automated dependency vulnerability and provenance scanning into maintenance workflows. - Update pinned versions through a controlled review and testing process. - Replace the generic installation message with a reference to the project's reviewed installation procedure.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Credential Access

High
Category
Privilege Escalation
Content
except paramiko.SSHException:
			continue

	raise ValueError(f"Unable to read private key at {key_path}")


def run_command(
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The documentation promotes remote command execution and logging of command results without clearly warning users about the risks of running arbitrary commands on remote hosts or exposing sensitive data in logs. In this context, the omission increases the chance of unsafe use, including destructive command execution and credential, secret, or system data leakage through logged output.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
This skill allows you to execute SSH commands on remote servers securely. It supports both password and key-based authentication methods, making it versatile for various use cases.
## Features
- **Authentication**: Supports both password and key-based authentication.
- **Command Execution**: Execute any command on the remote server and retrieve the output.
- **Error Handling**: Provides detailed error messages for failed command executions.
- **Logging**: Logs all executed commands and their results for auditing purposes.
## Prerequisites
Confidence
93% confidence
Finding
Advertising the ability to 'execute any command' on a remote server indicates unrestricted command execution capability with no documented guardrails, validation, or scope limits. In an SSH execution skill, this materially increases abuse potential because a user or downstream agent could run destructive administrative commands, exfiltrate data, alter configurations, or establish persistence on reachable systems.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The code disables SSH host key verification by default by using AutoAddPolicy() unless --strict-host-key is explicitly provided. This makes man-in-the-middle attacks feasible, allowing an attacker on the network to impersonate the target host, capture credentials, and tamper with commands or output; in an SSH execution skill, that context makes the issue especially dangerous because it directly affects remote administrative actions.

Static analysis

No suspicious patterns detected.