Back to skill

Security audit

SSH Config Manager

Security checks for vulnerabilities and agentic risk

Overview

This skill is a legitimate SSH config manager, but it edits sensitive SSH settings and tests connections in ways that need careful review before installation.

Install only if you are comfortable letting this skill read and modify SSH client configuration. Review changes before applying them, keep your own backup of ~/.ssh/config, avoid testing hosts from untrusted config files, and be aware that malformed entries could disrupt SSH access or change connection behavior.

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/main.py:274
Finding
SSH Command-Line Option Injection Through an Unvalidated Hostname<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 274-291 **Vulnerability Type**: SSH command-line option injection **Risk Level**: High ### Vulnerable Code ```python if 'user' in options: sshname = f"{options['user']}@{options['hostname']}" else: sshname = options['hostname'] ssh_command.extend([sshname, 'exit']) try: start_time = time.time() result = subprocess.run( ssh_command, capture_output=True, text=True, timeout=timeout + 2 ) ``` ### Technical Analysis The destination passed to `ssh` is taken from the parsed `Hostname` option without validation. If no username is present and the hostname begins with `-`, OpenSSH may interpret the value as a command-line option rather than as the destination. Although `subprocess.run` uses an argument list and does not invoke a shell, this only prevents shell metacharacter expansion. It does not prevent option injection into the invoked SSH client. A value resembling an SSH option, including a dangerous `ProxyCommand` configuration, may alter SSH behavior or cause a local process to be launched. The Skill supports arbitrary configuration files through `--config`, so exploitation does not necessarily require modification of the user's default SSH configuration. ### Attack Path 1. An attacker supplies or modifies an SSH configuration file that the victim will inspect with the Skill. 2. The attacker adds a host entry whose `Hostname` begins with an SSH option, such as a value representing `-oProxyCommand=...`. 3. The entry omits `User` so that the value remains the first component of `sshname`. 4. The victim runs: ```bash python3 scripts/main.py test --host malicious --config attacker-config ``` 5. The Skill places the attacker-controlled value into the SSH argument vector before the intended destination. 6. The SSH client interprets the value as an option and may execute the configured proxy command under the victim's local ...[truncated 444 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject hostnames and usernames that begin with `-`. 2. Validate hostnames against strict hostname, IPv4, or IPv6 syntax and validate usernames against an appropriate allowlist. 3. Insert an SSH-supported end-of-options delimiter before the destination where compatibility permits. 4. Explicitly disable dangerous SSH behaviors during tests, including `ProxyCommand`, `LocalCommand`, and `PermitLocalCommand`. 5. Consider invoking SSH with the selected host alias and a controlled configuration file rather than reconstructing a destination from untrusted configuration values. 6. Add regression tests covering values such as `-oProxyCommand=...`, `-F...`, and other option-shaped hostnames. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:25
Finding
SSH Configuration Backups and New Configuration Files Are Created Without Enforced Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 25-41 and 132-140 **Vulnerability Type**: Insecure permissions for sensitive SSH configuration data **Risk Level**: Medium ### Vulnerable Code ```python self.backup_dir = os.path.expanduser("~/.ssh/backups") # Create backup directory if it doesn't exist os.makedirs(self.backup_dir, exist_ok=True) def backup_config(self) -> str: """Create a backup of the current config file.""" if not os.path.exists(self.config_path): return "" timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S") backup_path = os.path.join(self.backup_dir, f"config_backup_{timestamp}") try: with open(self.config_path, 'r') as src: with open(backup_path, 'w') as dst: dst.write(src.read()) ``` The main configuration is also written without enforcing a secure mode: ```python def write_config(self, hosts: List[Dict[str, Any]]) -> bool: """Write hosts back to SSH config file.""" try: with open(self.config_path, 'w') as f: for host in hosts: f.write(f"Host {host['host']}\n") for key, value in host['options'].items(): f.write(f" {key} {value}\n") f.write("\n") ``` ### Technical Analysis The backup directory and files are created using default process permissions. Their final modes therefore depend on the environment's `umask`. Under a common `022` umask, a newly created backup can be readable by other local users. SSH configuration files may contain internal hostnames, usernames, proxy routes, network topology, and paths to private identity files. The implementation does not read or copy private-key contents, but disclosure of SSH configuration metadata can still materially assist later attacks. The direct write to the destination also lacks an atomic replacement workflow. If the process is interrupted, the existing configuration may be left ...[truncated 962 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create SSH-related directories with mode `0700`. 2. Create backup and configuration files with mode `0600`, using `os.open` with explicit creation flags and permissions where appropriate. 3. Verify and repair permissions on existing backup directories and files. 4. Preserve safe ownership and permissions when replacing an existing configuration. 5. Write updates to a temporary file created securely in the same directory, flush and synchronize it, set mode `0600`, and then use `os.replace` for atomic replacement. 6. Reject symbolic-link destinations or use file-opening safeguards that prevent symlink-following where supported. 7. Report backup failures as update-blocking errors rather than continuing to overwrite the configuration without a valid backup. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (16)

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/main.py list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
--hostname server.example.com \
  --user ec2-user \
  --port 2222 \
  --identity ~/.ssh/id_rsa \
  --tag "aws,production" \
  --description "Production web server"
```
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises capabilities to read and write files and invoke shell commands, but it does not declare any explicit tool scope or permission boundaries. For a tool that edits `~/.ssh/config` and tests SSH connections, the absence of scoped permissions increases the chance of overbroad file modification or command execution beyond what a user would reasonably expect.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Describing add/remove/edit operations on `~/.ssh/config` without an explicit caution underplays the sensitivity of SSH client configuration. Even non-malicious edits can lock users out of hosts, redirect traffic via attacker-controlled options such as `ProxyCommand`, or weaken expected connection behavior if changes are applied carelessly.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documented `generate --output ~/.ssh/config` workflow can overwrite a critical authentication configuration file without a prominent warning about disruption risk. A malformed or unintended overwrite of `~/.ssh/config` can break access to infrastructure, alter routing through bastions/proxies, or cause users to connect with unsafe defaults.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
            start_time = time.time()
            result = subprocess.run(
                ssh_command,
                capture_output=True,
                text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Low
Confidence
89% confidence
Finding
This markdown file describes operations that alter the user's SSH configuration, including adding, editing, and removing hosts. Although it mentions backups before changes, it does not clearly warn users that the tool modifies a sensitive local config file whose mistakes could disrupt SSH access or connectivity.

Static analysis

No suspicious patterns detected.