Back to skill

Security audit

MCP SSH Manager

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent SSH-management guide, but it needs review because it includes unsafe privileged/destructive server examples and weak handling of persisted operational data.

Install only if you intend to let an agent assist with real SSH administration. Review every command before execution, especially sudo, uploads/syncs, restores, tunnels, and deletions. Do not copy the PHP-FPM `chmod 666` example; use least-privilege socket configuration instead. Store workdir outputs in private directories, redact secrets, and clean old operational records.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create-workdir.sh:39
Finding
Path Traversal Through Unvalidated Workdir Topic<![CDATA[ ## Vulnerability Details **File Location**: `scripts/create-workdir.sh:39-52` **Vulnerability Type**: Path traversal and arbitrary file overwrite **Risk Level**: Medium ### Vulnerable Code ```bash # Validate topic format if [[ ! "$TOPIC" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}- ]]; then echo -e "${YELLOW}Warning: Topic should start with YYYY-MM-DD- for consistency${NC}" fi # Create directory structure WORKDIR="${WORKDIR_BASE}/${HOSTNAME}/${TOPIC}" OUTPUT_DIR="${WORKDIR}/output" echo -e "${GREEN}Creating workdir...${NC}" echo " Hostname: ${HOSTNAME}" echo " Topic: ${TOPIC}" echo " Path: ${WORKDIR}" ``` The affected path is subsequently created and files within it are overwritten: ```bash mkdir -p "${OUTPUT_DIR}" touch "${WORKDIR}/commands.md" touch "${WORKDIR}/summary.md" cat > "${WORKDIR}/commands.md" << EOF ``` ### Technical Analysis The `TOPIC` argument is incorporated directly into `WORKDIR`. The script checks only whether it starts with a date-like prefix, and a failed check produces a warning rather than terminating execution. It does not reject path separators, `..` components, or other traversal syntax. Shell quoting prevents command injection but does not prevent filesystem path traversal. A value containing traversal components can cause the normalized path to leave `${HOME}/.ssh-workdir/${HOSTNAME}`. The script then creates directories and truncates `commands.md` and `summary.md` at the resulting location. The hostname validation is appropriately restrictive, but it does not compensate for the unrestricted topic component. ### Attack Path 1. An attacker obtains the ability to influence arguments passed to `create-workdir.sh`. 2. The attacker supplies a topic containing traversal components, such as a date-prefixed value followed by `/../../`. 3. The format check accepts the date prefix or merely emits a warning. 4. `mkdir -p` resolves the traversal and creates the resulting directory outside the intended host workdir. 5. The here- ...[truncated 743 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Treat an invalid topic as a fatal error rather than a warning. - Restrict topics to one safe path component, for example: ```bash if [[ ! "$TOPIC" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-zA-Z0-9._-]+$ ]]; then echo "Error: Invalid topic format" >&2 exit 1 fi ``` - Explicitly reject `/`, `\`, `..`, control characters, and empty components. - Canonicalize the base and destination with `realpath` and verify that the destination remains below the canonical base directory. - Use `mkdir --` and other utilities with `--` before attacker-influenced operands. - Add automated tests covering absolute paths, traversal components, repeated separators, and control characters. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/save-status.sh:27
Finding
Path Traversal and Attacker-Selected File Overwrite in Status Saving<![CDATA[ ## Vulnerability Details **File Location**: `scripts/save-status.sh:27-48` **Vulnerability Type**: Path traversal and arbitrary file overwrite **Risk Level**: Medium ### Vulnerable Code ```bash SERVER="$1" OUTPUT_FILE="${2:-status.json}" # Check for workdir (current directory) WORKDIR="${PWD}" if [ ! -f "${WORKDIR}/commands.md" ]; then echo -e "${YELLOW}Warning: Not in a workdir${NC}" WORKDIR="$HOME/.ssh-workdir/${SERVER}/$(date +%Y-%m-%d)-status" mkdir -p "${WORKDIR}/output" echo "Using: ${WORKDIR}" fi OUTPUT_PATH="${WORKDIR}/${OUTPUT_FILE}" echo -e "${GREEN}Capturing status for ${SERVER}...${NC}" echo "Output: ${OUTPUT_PATH}" # Create status snapshot STATUS=$(cat > "${OUTPUT_PATH}" << 'EOF' ``` ### Technical Analysis Neither `SERVER` nor `OUTPUT_FILE` is validated as a single safe path component. If the current directory contains `commands.md`, the caller can use traversal components in `OUTPUT_FILE` to write outside that directory. If the current directory is not recognized as a workdir, traversal components in `SERVER` can also move the generated path outside `~/.ssh-workdir`. The redirection used by `cat` creates the destination if absent and truncates it if present. Quoting prevents shell metacharacter expansion, but it does not stop `../` traversal. ### Attack Path 1. An attacker influences the server name or optional output filename supplied to the script. 2. The attacker provides a value containing one or more `../` components. 3. The script concatenates the value with the workdir without canonicalization or containment validation. 4. The operating system resolves the traversal components. 5. The `cat > "${OUTPUT_PATH}"` redirection creates or truncates the resolved target. 6. A fixed JSON template is written over the targeted file. ### Impact Assessment The script can overwrite any file writable by its invoking account. Potential consequences include: - Destruction or corruption of user files. - Replacement of a ...[truncated 469 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Validate `SERVER` using the same strict hostname allow-list used by `create-workdir.sh`. - Restrict `OUTPUT_FILE` to a basename with a safe extension: ```bash if [[ ! "$OUTPUT_FILE" =~ ^[a-zA-Z0-9._-]+\.json$ ]] || [[ "$OUTPUT_FILE" == *".."* ]]; then echo "Error: Invalid output filename" >&2 exit 1 fi ``` - Reject all path separators and control characters in both values. - Canonicalize the destination and verify that it starts with the canonical workdir followed by `/`. - Consider refusing to overwrite an existing file, or require an explicit `--force` option. - Create files atomically using a temporary file inside the verified workdir followed by `mv`. - Add `umask 077` to ensure that generated status data is private. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create-workdir.sh:94
Finding
Persisted SSH Operational Output Is Not Consistently Protected<![CDATA[ ## Vulnerability Details **File Location**: `scripts/create-workdir.sh:94-97` **Vulnerability Type**: Insecure permissions for potentially sensitive operational records **Risk Level**: Medium ### Vulnerable Code ```bash # Set permissions chmod 700 "${WORKDIR}" chmod 600 "${WORKDIR}/commands.md" chmod 600 "${WORKDIR}/summary.md" chmod 755 "${OUTPUT_DIR}" ``` The documented workflows then persist remote output in that directory, including logs, configurations, network state, process information, and login history. Representative examples include: ```bash ssh_session_send session="sess-xxx" command="tail -50 /var/log/nginx/error.log" > ~/.ssh-workdir/rock-5t/2026-02-07-nginx-502/output/nginx-error.txt ssh_session_send session="sess-xxx" command="cat /etc/nginx/sites-available/default" > ~/.ssh-workdir/rock-5t/2026-02-07-nginx-502/config/nginx-site.txt ``` ### Technical Analysis The script explicitly protects `commands.md` and `summary.md`, but sets the output directory to mode `0755` and does not set a restrictive process umask or file mode for subsequently redirected output. The top-level workdir created by this script is mode `0700`, which limits traversal in the normal case. However, the broader documentation frequently creates workdirs manually with `mkdir -p`, without setting the parent directory to `0700`. In those workflows, the final output file mode is inherited from the caller's umask. With a common umask of `022`, redirected files are generally created as `0644`. Remote command output may contain: - Internal addresses and service topology. - Usernames and login history. - Process and container details. - Application error messages. - Repository URLs and deployment metadata. - Configuration values or credentials accidentally emitted by applications. The static pre-scan references to `~/.ssh-workdir` do not indicate access to SSH private keys. The directory merely has an SSH-related name. The risk is instead the persistent retention of ...[truncated 1070 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Add `umask 077` near the beginning of every script. - Set every workdir subdirectory, including `output` and `config`, to mode `0700`. - Explicitly create output files with mode `0600`, rather than relying on the caller's umask. - Update all manual documentation examples to run `install -d -m 700` instead of plain `mkdir -p`. - Warn users not to retain passwords, tokens, private keys, environment dumps, or complete configuration files unless necessary. - Redact common credential patterns before persistence. - Introduce a configurable retention policy and document secure deletion. - Require explicit confirmation before storing authentication logs or configuration files likely to contain secrets. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
examples/troubleshooting.md:141
Finding
Troubleshooting Workflow Makes the PHP-FPM Socket World Writable<![CDATA[ ## Vulnerability Details **File Location**: `examples/troubleshooting.md:141-153` **Vulnerability Type**: Excessive permissions on a privileged service socket **Risk Level**: High ### Vulnerable Code ```bash # Check socket permissions ssh_session_send session="sess-xxx" command="ls -la /run/php/php8.2-fpm.sock" ``` ```bash # Fix socket ownership ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock" ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock" # Restart services ssh_session_send session="sess-xxx" command="sudo systemctl restart php8.2-fpm" ssh_session_send session="sess-xxx" command="sudo systemctl restart nginx" ``` The unsafe permission is also repeated later in the generated troubleshooting summary: ```bash sudo chown www-data:www-data /run/php/php8.2-fpm.sock sudo chmod 666 /run/php/php8.2-fpm.sock sudo systemctl restart php8.2-fpm sudo systemctl restart nginx ``` ### Technical Analysis Mode `0666` grants read and write access to every local user. For a Unix-domain FastCGI socket, write access allows an unprivileged local process to communicate directly with PHP-FPM rather than passing through nginx. This breaks least privilege. Only the web server account or a dedicated authorized group should be able to connect to the socket. The document later recommends the safer permanent configuration `listen.mode = 0660`, showing that world access is unnecessary for the declared troubleshooting task. Restarting PHP-FPM may recreate the socket with configured permissions, but the guidance still creates an unsafe window and may remain effective if the service configuration reproduces or preserves the permissive mode. ### Attack Path 1. An administrator or agent follows the documented troubleshooting procedure with sudo privileges. 2. The command changes `/run/php/php8.2-fpm.sock` to mode `0666`. 3. A local unprivileged attacker discovers the world-writable socket ...[truncated 1046 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove every recommendation to use `chmod 666` on the PHP-FPM socket. - Configure access permanently in the relevant PHP-FPM pool: ```ini listen.owner = www-data listen.group = www-data listen.mode = 0660 ``` - If nginx and PHP-FPM use different accounts, create or select a dedicated group and add only the required service accounts to it. - Restart PHP-FPM so that it recreates the socket with the configured ownership and mode. - Verify the result with: ```bash stat -c '%U %G %a %n' /run/php/php8.2-fpm.sock ``` - Confirm that unauthorized local users cannot connect to the socket. - Require explicit operator approval before running privileged ownership, permission, configuration, or service-restart commands. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (43)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
There is a clear mismatch between the declared purpose and the actual code. The description promises remote server management capabilities centered on SSH operations and related workflows. The code instead performs a narrow local task: appending a supplied command string with a timestamp to commands.md in the current working directory. This is not a supporting implementation detail of SSH execution in the supplied chunk; it is the entirety of the shown behavior and represents a different primary purpose. Therefore the description does not accurately represent what this code chunk actually does.

Missing User Warnings

High
Confidence
97% confidence
Finding
The rollback procedure instructs the agent to perform destructive deletion of remote application contents during rollback without an explicit warning, validation of the target directory, or user confirmation. In an SSH-management skill, this is especially dangerous because a path mistake, unexpected shell state, or misuse of the session/command parameters could irreversibly wipe remote files on a production server.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
ssh_session_start server="rock-5t" name="rollback-2026-02-07"

# Restore backup
ssh_session_send session="sess-xxx" command="cd /home/imax/app && rm -rf *"
ssh_session_send session="sess-xxx" command="cd /home/imax/app && tar -xzf ~/.ssh-workdir/rock-5t/2026-02-07-deployment/rollback/backup-20260207.tar.gz"

# Restart service
Confidence
98% confidence
Finding
The tool parameter contains a raw destructive shell command, `cd /home/imax/app && rm -rf *`, sent for remote execution over SSH. This is dangerous because the tool accepts free-form command strings, so any quoting issue, directory mismatch, glob expansion surprise, or parameter substitution problem can turn a rollback step into broad remote data destruction.

Chaining Abuse

High
Category
Tool Misuse
Content
ssh_session_start server="rock-5t" name="rollback-2026-02-07"

# Restore backup
ssh_session_send session="sess-xxx" command="cd /home/imax/app && rm -rf *"
ssh_session_send session="sess-xxx" command="cd /home/imax/app && tar -xzf ~/.ssh-workdir/rock-5t/2026-02-07-deployment/rollback/backup-20260207.tar.gz"

# Restart service
Confidence
95% confidence
Finding
The command chains directory change and deletion with `&&`, concentrating safety-critical assumptions into one opaque remote shell string. In this skill context, chaining increases danger because the agent cannot independently validate each step, and a malformed or unexpectedly evaluated command can still lead to destructive behavior against production files.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
Confidence
93% confidence
Finding
This finding reflects unsafe command payloads being sent through the SSH management tool, specifically combining privileged ownership changes with a world-writable socket permission command. In a tool that executes remote commands, showcasing insecure parameters as standard usage can directly lead to exploitable server misconfiguration.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Fix Applied
```bash
sudo chown www-data:www-data /run/php/php8.2-fpm.sock
sudo chmod 666 /run/php/php8.2-fpm.sock
sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx
Confidence
92% confidence
Finding
The summary embeds the same insecure command sequence as a recommended fix, effectively promoting dangerous tool parameters for remote execution. Because this skill is specifically for SSH-based server management, harmful example commands are more likely to be reused verbatim in production.

Lp3

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding
The skill documents shell-style command execution and file/system operations but does not declare any explicit tool scope such as allowed-tools or permissions. In an agent environment, missing scope boundaries can let the skill be invoked with broader-than-intended execution capabilities, reducing reviewability and policy enforcement.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger conditions are extremely broad and can activate the skill for many remote-operation requests without sufficient narrowing or confirmation. In a powerful SSH context, ambiguous routing increases the chance that sensitive or destructive server actions are initiated under the wrong circumstances.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The documentation normalizes remote command execution, including sudo usage, without requiring user confirmation or warning about system impact. Because these actions can modify packages, services, or system state on remote hosts, omission of safety gates materially increases the risk of harmful execution.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
|------|------|---------|
| List servers | `ssh_list_servers` | `ssh_list_servers` |
| Execute command | `ssh_execute` | `ssh_execute server="rock5t" command="df -h"` |
| Execute with sudo | `ssh_execute_sudo` | `ssh_execute_sudo server="rock5t" command="apt update"` |
| Check status | `ssh_connection_status` | `ssh_connection_status action="status"` |

### Session Management
Confidence
81% confidence
Finding
The skill explicitly includes sudo-based remote execution, which elevates the consequences of misuse or prompt-routing mistakes. While privilege use is expected in some SSH administration scenarios, documenting it without stronger safeguards makes accidental or unauthorized high-impact changes more likely.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
File upload, download, and sync actions are presented as routine without warning about overwrite, data loss, or deployment impact. In remote environments, these operations can replace application files, expose sensitive data, or disrupt running services if used incorrectly.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
Backup restore is inherently disruptive and potentially irreversible, yet the skill presents it without strong cautions or approval checkpoints. An agent following this guidance could restore incorrect data, overwrite current state, or cause downtime on production systems.

Ssd 3

Medium
Confidence
93% confidence
Finding
The workdir guidance instructs persistent storage of executed commands and outputs under predictable local paths. SSH command outputs commonly contain secrets, hostnames, internal topology, logs, and operational data, so retaining them in plaintext creates a local data exposure and accumulation risk.

Ssd 3

Medium
Confidence
90% confidence
Finding
The best-practices section encourages routine saving of outputs and summaries, which creates a durable record of potentially sensitive server state and findings. Repeated accumulation of such data increases the blast radius of local compromise and may violate least-retention principles.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The workflow explicitly saves outputs from commands like `netstat -tulpn`, `ss -tulpn`, `docker ps -a`, `who`, and `last` into persistent local files. These outputs can contain sensitive operational and user activity data such as listening services, usernames, login history, container names, and internal network details, yet the example provides no warning about sensitivity, retention, access controls, or redaction.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The example claims to fix PHP-FPM socket access by correcting ownership, but it also instructs `chmod 666` on the Unix socket, making it world-writable. That weakens local privilege boundaries and can allow unintended local processes to interact with the backend service socket, creating an insecure workaround rather than a proper fix.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This section performs privileged changes to a live remote system, including permission changes and service restarts, without warning about service disruption, validation steps, or rollback. In an SSH-management skill, operators may copy these commands directly, so missing safety guidance increases the chance of outages or insecure emergency fixes being applied in production.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
ssh_session_send session="sess-xxx" command="sudo systemctl restart php8.2-fpm"
Confidence
99% confidence
Finding
The matched `chmod 666` is an unsafe permission change on a service socket, granting all users write access. In the context of an SSH management skill intended for real server operations, this is especially dangerous because readers may execute it directly on production systems.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Fix socket ownership
ssh_session_send session="sess-xxx" command="sudo chown www-data:www-data /run/php/php8.2-fpm.sock"
ssh_session_send session="sess-xxx" command="sudo chmod 666 /run/php/php8.2-fpm.sock"

# Restart services
ssh_session_send session="sess-xxx" command="sudo systemctl restart php8.2-fpm"
Confidence
99% confidence
Finding
The matched `chmod 666` is an unsafe permission change on a service socket, granting all users write access. In the context of an SSH management skill intended for real server operations, this is especially dangerous because readers may execute it directly on production systems.

Static analysis

No suspicious patterns detected.