Back to skill

Security audit

Deepspeed Finetune

Security checks for vulnerabilities and agentic risk

Overview

This DeepSpeed fine-tuning skill is mostly coherent, but its remote SSH helper creates lasting passwordless access and uses unsafe SSH practices that require careful review.

Install only if you trust the publisher and are comfortable granting the skill remote SSH control. Use a dedicated unprivileged remote account, avoid password-based SSH where possible, verify host keys out of band, do not enable trust_remote_code for unreviewed models, and remove any generated key from both the local machine and remote authorized_keys when finished.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (5)

T06 · System Persistence

Error
Location
scripts/remote_train.py:480
Finding
Persistent Passwordless SSH Access Installed on Remote Systems<![CDATA[ ## Vulnerability Details **File Location**: `scripts/remote_train.py:480-520`; related workflow in `references/remote_training.md:106-118` **Vulnerability Type**: Persistent SSH authorization **Risk Level**: Critical ### Vulnerable Code ```python # 1. Generate key pair (no passphrase) if os.path.exists(DEFAULT_KEY_PATH): print(f"Key already exists: {DEFAULT_KEY_PATH}") overwrite = input("Overwrite? (y/N): ").strip().lower() if overwrite != 'y': print("Cancelled") sys.exit(1) print(f"Generating key pair...") keygen_cmd = [ "ssh-keygen", "-t", "ed25519", "-f", DEFAULT_KEY_PATH, "-N", "", "-C", "deepspeed-remote" ] result = subprocess.run(keygen_cmd, capture_output=True, text=True) if result.returncode != 0: print(f"Key generation failed: {result.stderr}") sys.exit(1) os.chmod(DEFAULT_KEY_PATH, 0o600) os.chmod(f"{DEFAULT_KEY_PATH}.pub", 0o644) # 2. Read public key pub_key_path = f"{DEFAULT_KEY_PATH}.pub" with open(pub_key_path) as f: pub_key = f.read().strip() # 3. Auto-upload public key via SSH (password available) pub_key_b64 = base64.b64encode(pub_key.encode()).decode() remote_setup = ( f"mkdir -p ~/.ssh && " f"chmod 700 ~/.ssh && " f"touch ~/.ssh/authorized_keys && " f"chmod 600 ~/.ssh/authorized_keys && " f"grep -qF '{pub_key_b64}' ~/.ssh/.deepspeed_setup_marker 2>/dev/null || " f"(echo '{pub_key_b64}' >> ~/.ssh/.deepspeed_setup_marker && " f"echo '{pub_key_b64}' | base64 -d >> ~/.ssh/authorized_keys)" ) ``` ### Technical Analysis The `setup-keys` workflow generates an SSH private key with an empty passphrase and appends its public key to the remote account's `~/.ssh/authorized_keys`. This creates an authorization mechanism that remains valid after the training process and SSH ControlMaster session have ended. The operation is related to remote training, but it exceeds the minimum access duration required to launch or monitor an individual training job. The `s ...[truncated 1434 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit, informed confirmation immediately before modifying `authorized_keys`. 2. Clearly state that the key grants continuing login access after training ends. 3. Generate a unique, task-scoped key for each remote job rather than reusing a global key. 4. Revoke the public key automatically when training completes, is stopped, or expires. 5. Securely delete the corresponding local task key after revocation. 6. Add restrictive authorized-key options where possible, such as: - `from="<trusted-source-address>"` - `command="<restricted-training-wrapper>"` - `no-agent-forwarding` - `no-port-forwarding` - `no-X11-forwarding` - `no-pty` 7. Prefer an existing user-managed SSH agent or credential rather than creating a new persistent identity. 8. Add a dedicated cleanup command that reliably removes both the public key and `.deepspeed_setup_marker`. 9. Avoid using a privileged remote account when a dedicated, restricted training account is sufficient. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/remote_train.py:105
Finding
SSH Host Authenticity Verification Is Disabled<![CDATA[ ## Vulnerability Details **File Location**: `scripts/remote_train.py:105-110`; repeated at lines `141-146`, `175-181`, `191-198`, `233-247`, `537-541`, and `591-597` **Vulnerability Type**: Improper SSH host verification **Risk Level**: High ### Vulnerable Code ```python def _build_ssh_base(host, port, use_key=True): """Build base SSH argument list (without password).""" cmd = [ "ssh", "-o", "StrictHostKeyChecking=no", "-o", "ServerAliveInterval=30", "-o", "ConnectTimeout=10", "-p", str(port), ] ``` The same option is also applied to password authentication, ControlMaster creation, SCP uploads, key verification, and key installation: ```python ssh_cmd = [ "sshpass", "-p", password, "ssh", "-o", "StrictHostKeyChecking=no", "-o", "ServerAliveInterval=30", "-o", "ConnectTimeout=10", "-p", str(port), host, cmd ] ``` ### Technical Analysis `StrictHostKeyChecking=no` permits automated connections without first establishing a trusted binding between the server identity and its SSH host key. This removes an essential authentication property from the SSH workflow. The guide acknowledges the risk but incorrectly treats switching to client-key authentication as a mitigation. Client-key authentication authenticates the client to the server; it does not establish that the client has reached the intended server. Similarly, blindly obtaining a fingerprint with `ssh-keyscan` over the same untrusted network does not prevent interception. ### Attack Path 1. An attacker gains a position capable of influencing DNS resolution, routing, or local network traffic. 2. The attacker presents an SSH service using an attacker-controlled host key. 3. The Skill accepts the untrusted host because strict host checking is disabled. 4. The user-supplied SSH password may be presented to the attacker's server during authentication. 5. Training scripts may be uploaded to the attacker-controlled endpoint. 6. Th ...[truncated 551 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `StrictHostKeyChecking=no` with `StrictHostKeyChecking=yes`. 2. Use a dedicated `UserKnownHostsFile` owned by the Skill user and protected with restrictive permissions. 3. Obtain the expected SSH host-key fingerprint through a separately authenticated channel. 4. Require the user to verify and approve the fingerprint before the first connection. 5. Pin the approved key and fail closed if it changes. 6. Apply the same verified-host policy consistently to SSH, SCP, ControlMaster setup, password login, and key verification. 7. Do not treat client-key authentication or unauthenticated `ssh-keyscan` output as server identity verification. 8. Display a clear error and require a deliberate re-enrollment process when the host key changes. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/remote_train.py:259
Finding
Remote Command Injection Through Incorrect POSIX Shell Escaping<![CDATA[ ## Vulnerability Details **File Location**: `scripts/remote_train.py:58-61` and `scripts/remote_train.py:259-269` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```python def _shell_safe(s): """Shell-escape a string to prevent command injection.""" return subprocess.list2cmdline([s]) ``` ```python # 5. Launch remote training via tmux log_path = f"{args.remote_dir}/{args.log}" safe_dir = _shell_safe(args.remote_dir) safe_python = _shell_safe(args.remote_python) safe_script = _shell_safe(os.path.basename(args.script)) safe_log = _shell_safe(log_path) safe_session = _shell_safe(TMUX_SESSION_NAME) remote_cmd = ( f"tmux new-session -d -s {safe_session} " f"\"cd {safe_dir} && exec {safe_python} -u {safe_script} > {safe_log} 2>&1\"" ) print(f"Launching training on {host}...") stdout, stderr, code = _ssh_exec(host, port, remote_cmd, timeout=30) ``` ### Technical Analysis `subprocess.list2cmdline` implements quoting rules for Windows command-line parsing. It is not a POSIX shell-escaping function. The generated values are subsequently interpolated into a command evaluated by the remote Unix shell. Inputs such as `--remote-dir`, `--remote-python`, and `--log` can therefore retain shell metacharacters or command substitutions. The nested double-quoted `tmux` command increases the parsing complexity and makes correct escaping more difficult. For example, a crafted value containing command substitution may be evaluated by the remote shell when `remote_cmd` is executed. This is especially significant because the CLI allows the caller to control all affected arguments. ### Attack Path 1. An attacker obtains influence over launch arguments, an automated job definition, or an Agent instruction that supplies remote-training parameters. 2. The attacker inserts POSIX shell syntax into `--remote-dir`, `--remote-python`, or `--log`. 3. `_shell_safe` applies Windows quoting rather than POSIX escaping. 4. The cra ...[truncated 653 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `subprocess.list2cmdline` with POSIX-aware escaping such as `shlex.quote` for commands that must be evaluated by a Unix shell. 2. Apply escaping independently at each shell-parsing layer; avoid nesting a shell command inside quoted `tmux` arguments. 3. Prefer uploading a fixed launcher script and passing validated parameters through JSON or another structured data format. 4. Validate `--remote-python` against an allowlist of expected executable paths. 5. Normalize and validate `--remote-dir` and log paths, rejecting: - Newlines and control characters - Shell metacharacters - Command substitutions - Unexpected path traversal 6. Avoid accepting arbitrary executable expressions where a fixed `python3` command is sufficient. 7. Add security tests using inputs containing spaces, quotes, semicolons, backticks, dollar-sign substitutions, redirects, and newlines. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/remote_train.py:135
Finding
SSH Password Copied into Child Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/remote_train.py:135-148`; repeated at lines `187-200`, `241-249`, and `588-598` **Vulnerability Type**: Sensitive information exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```python # Fallback: use password (read from env var only) password = _get_password() if not password: return "", "Authentication failed: no usable key and REMOTE_SSH_PASSWORD not set", 1 ssh_cmd = [ "sshpass", "-p", password, "ssh", "-o", "StrictHostKeyChecking=no", "-o", "ServerAliveInterval=30", "-o", "ConnectTimeout=10", "-p", str(port), host, cmd ] try: result = subprocess.run( ssh_cmd, capture_output=True, text=True, timeout=timeout ) ``` ### Technical Analysis The password initially enters the program through `REMOTE_SSH_PASSWORD`, but the code then places it after the `sshpass -p` option in the child process's argument vector. Consequently, the documentation's statement that passwords are passed through environment variables only is incomplete: the secret is converted into a command-line argument during execution. Process arguments may be visible through process-inspection interfaces, monitoring agents, audit systems, diagnostic tooling, or crash telemetry. Exact visibility depends on operating-system configuration and process ownership, but secrets should not be placed in an argument vector. ### Attack Path 1. A user launches a remote operation with `REMOTE_SSH_PASSWORD` set. 2. The script reads the password and constructs `sshpass -p <password>`. 3. The child process remains active while connecting or performing a remote operation. 4. A local user or monitoring component with sufficient process-inspection access reads the argument vector. 5. The observer recovers the remote SSH password and may reuse it against the target server. ### Impact Assessment Exposure compromises the remote account password. The privileges o ...[truncated 262 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not use `sshpass -p`. 2. If `sshpass` is unavoidable, use `sshpass -e` with `SSHPASS` supplied only to the child process through a narrowly scoped environment. 3. Consider passing the secret through an inherited file descriptor if supported by the selected authentication tool. 4. Prefer a user-managed SSH agent or an existing protected private key. 5. Remove misleading documentation claiming that the password remains environment-only throughout execution. 6. Ensure debugging, exception handling, and subprocess logging never print the child environment or command arguments. 7. Use a dedicated, least-privileged remote account with a short-lived password or token. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/ds_train.py:188
Finding
Optional Execution of Code Supplied by Remote Model Repositories<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ds_train.py:68-71` and `scripts/ds_train.py:188-220` **Vulnerability Type**: Unpinned remote code execution through model loading **Risk Level**: Medium ### Vulnerable Code ```python trust_remote_code: bool = field( default=False, metadata={"help": "Whether to trust remote code when loading model"} ) ``` ```python # Load tokenizer tokenizer = AutoTokenizer.from_pretrained( model_args.model_name_or_path, trust_remote_code=model_args.trust_remote_code, padding_side="right", ) # Set pad token if not set if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token # Determine torch dtype if model_args.torch_dtype == "auto": torch_dtype = ( torch.bfloat16 if torch.cuda.is_available() and torch.cuda.is_bf16_supported() else torch.float16 ) else: torch_dtype = getattr(torch, model_args.torch_dtype) # Load model model_kwargs = { "torch_dtype": torch_dtype, "trust_remote_code": model_args.trust_remote_code, } model = AutoModelForCausalLM.from_pretrained( model_args.model_name_or_path, **model_kwargs ) ``` ### Technical Analysis The safe default is `False`, but the exposed `trust_remote_code` option permits Python implementation code associated with a selected model repository to be downloaded and executed in the training process. No repository allowlist, immutable revision pin, code-signing check, local review requirement, or sandbox boundary is enforced. Therefore, the effective executable payload can change after this Skill has been reviewed if a mutable model repository or branch is used. The risk requires the option to be deliberately enabled, but the project documentation recommends enabling it as a troubleshooting step for some model-loading errors. ### Attack Path 1. An attacker publishes or compromises a model repository containing custom model or tokenizer code. 2. A user or Agent selects that reposi ...[truncated 754 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Keep `trust_remote_code` disabled by default. 2. Require explicit confirmation that explains remote Python code will execute before enabling it. 3. Pin the model to an immutable, reviewed commit revision rather than a mutable branch or tag. 4. Maintain an allowlist of approved repositories and revisions. 5. Download and review custom model code before use. 6. Run workloads requiring remote code in an isolated container or sandbox with: - No SSH credentials - No cloud credentials - Restricted network access - Read-only input datasets where practical - A dedicated unprivileged user - Minimal mounted filesystem access 7. Record the repository identity, revision, and file hashes in training metadata for reproducibility and incident response. 8. Revise troubleshooting guidance so enabling remote code is presented as a security-sensitive last resort, not a routine compatibility fix. ]]>
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (46)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
If the skill in fact supports arbitrary remote SSH command execution, credential setup, file transfer, tmux/session management, and password-based fallback while presenting itself mainly as a fine-tuning skill, that is a significant security concern. Concealed or under-declared remote orchestration expands attack surface, can enable lateral movement or data exfiltration on remote hosts, and makes users more likely to authorize risky behavior without informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
If the skill in fact supports arbitrary remote SSH command execution, credential setup, file transfer, tmux/session management, and password-based fallback while presenting itself mainly as a fine-tuning skill, that is a significant security concern. Concealed or under-declared remote orchestration expands attack surface, can enable lateral movement or data exfiltration on remote hosts, and makes users more likely to authorize risky behavior without informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
If the skill in fact supports arbitrary remote SSH command execution, credential setup, file transfer, tmux/session management, and password-based fallback while presenting itself mainly as a fine-tuning skill, that is a significant security concern. Concealed or under-declared remote orchestration expands attack surface, can enable lateral movement or data exfiltration on remote hosts, and makes users more likely to authorize risky behavior without informed consent.

Credential Access

High
Category
Privilege Escalation
Content
## Security Notes

- **Host Key Verification**: SSH connections use `StrictHostKeyChecking=no`, which skips host key verification. This is necessary for automated password-based connections (sshpass doesn't support interactive host key prompts), but exposes the connection to potential man-in-the-middle attacks. **Mitigation**: After initial setup, configure SSH key authentication and run `ssh-keyscan <host> >> ~/.ssh/known_hosts` to permanently trust the host key. Subsequent connections via ControlMaster will use the saved host key.
- **Passwords**: Passed to child processes via environment variables only, never written to any file
- **Session file**: `.remote_train_session.json` only stores non-sensitive info (host, port, pid, log path, etc.)
- **SSH ControlMaster socket**: Stored in system temp directory. Recommend periodic cleanup: `rm -rf /tmp/deepspeed_remote_ssh/`
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **Host Key Verification**: SSH connections use `StrictHostKeyChecking=no`, which skips host key verification. This is necessary for automated password-based connections (sshpass doesn't support interactive host key prompts), but exposes the connection to potential man-in-the-middle attacks. **Mitigation**: After initial setup, configure SSH key authentication and run `ssh-keyscan <host> >> ~/.ssh/known_hosts` to permanently trust the host key. Subsequent connections via ControlMaster will use the saved host key.
- **Passwords**: Passed to child processes via environment variables only, never written to any file
- **Session file**: `.remote_train_session.json` only stores non-sensitive info (host, port, pid, log path, etc.)
- **SSH ControlMaster socket**: Stored in system temp directory. Recommend periodic cleanup: `rm -rf /tmp/deepspeed_remote_ssh/`

## Session Management
Confidence
90% 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).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **Host Key Verification**: SSH connections use `StrictHostKeyChecking=no`, which skips host key verification. This is necessary for automated password-based connections (sshpass doesn't support interactive host key prompts), but exposes the connection to potential man-in-the-middle attacks. **Mitigation**: After initial setup, configure SSH key authentication and run `ssh-keyscan <host> >> ~/.ssh/known_hosts` to permanently trust the host key. Subsequent connections via ControlMaster will use the saved host key.
- **Passwords**: Passed to child processes via environment variables only, never written to any file
- **Session file**: `.remote_train_session.json` only stores non-sensitive info (host, port, pid, log path, etc.)
- **SSH ControlMaster socket**: Stored in system temp directory. Recommend periodic cleanup: `rm -rf /tmp/deepspeed_remote_ssh/`

## Session Management
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).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **Host Key Verification**: SSH connections use `StrictHostKeyChecking=no`, which skips host key verification. This is necessary for automated password-based connections (sshpass doesn't support interactive host key prompts), but exposes the connection to potential man-in-the-middle attacks. **Mitigation**: After initial setup, configure SSH key authentication and run `ssh-keyscan <host> >> ~/.ssh/known_hosts` to permanently trust the host key. Subsequent connections via ControlMaster will use the saved host key.
- **Passwords**: Passed to child processes via environment variables only, never written to any file
- **Session file**: `.remote_train_session.json` only stores non-sensitive info (host, port, pid, log path, etc.)
- **SSH ControlMaster socket**: Stored in system temp directory. Recommend periodic cleanup: `rm -rf /tmp/deepspeed_remote_ssh/`

## Session Management
Confidence
90% 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).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
2. **Specify dtype:** `--torch_dtype bfloat16`
3. **Trust remote code:** `--trust_remote_code true`
4. **Upgrade transformers:** `pip install --upgrade transformers`
5. **Clear cache:** `rm -rf ~/.cache/huggingface/`

### Issue 12: LoRA Adapter Issues
Confidence
90% 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).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
2. **Specify dtype:** `--torch_dtype bfloat16`
3. **Trust remote code:** `--trust_remote_code true`
4. **Upgrade transformers:** `pip install --upgrade transformers`
5. **Clear cache:** `rm -rf ~/.cache/huggingface/`

### Issue 12: LoRA Adapter Issues
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).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
2. **Specify dtype:** `--torch_dtype bfloat16`
3. **Trust remote code:** `--trust_remote_code true`
4. **Upgrade transformers:** `pip install --upgrade transformers`
5. **Clear cache:** `rm -rf ~/.cache/huggingface/`

### Issue 12: LoRA Adapter Issues
Confidence
90% 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).

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The remote-exec feature provides unrestricted arbitrary command execution on the remote host, which goes well beyond model fine-tuning and effectively turns the skill into a generic remote shell wrapper. In this context, any caller with access to the skill can run destructive commands, access sensitive data, or establish persistence on managed GPU servers.

Credential Access

High
Category
Privilege Escalation
Content
remote_setup = (
        f"mkdir -p ~/.ssh && "
        f"chmod 700 ~/.ssh && "
        f"touch ~/.ssh/authorized_keys && "
        f"chmod 600 ~/.ssh/authorized_keys && "
        f"grep -qF '{pub_key_b64}' ~/.ssh/.deepspeed_setup_marker 2>/dev/null || "
        f"(echo '{pub_key_b64}' >> ~/.ssh/.deepspeed_setup_marker && "
Confidence
96% confidence
Finding
The code programmatically creates and modifies ~/.ssh/authorized_keys on the remote system, altering login credentials and establishing future access. In a training skill, this is highly sensitive because it can enable persistent administrative entry to remote servers beyond the immediate task.

Credential Access

High
Category
Privilege Escalation
Content
f"mkdir -p ~/.ssh && "
        f"chmod 700 ~/.ssh && "
        f"touch ~/.ssh/authorized_keys && "
        f"chmod 600 ~/.ssh/authorized_keys && "
        f"grep -qF '{pub_key_b64}' ~/.ssh/.deepspeed_setup_marker 2>/dev/null || "
        f"(echo '{pub_key_b64}' >> ~/.ssh/.deepspeed_setup_marker && "
        f"echo '{pub_key_b64}' | base64 -d >> ~/.ssh/authorized_keys)"
Confidence
96% confidence
Finding
This line participates in setting up and securing the authorized_keys file that will be used to grant SSH access, which is credential-management behavior outside the expected scope of fine-tuning orchestration. Unauthorized or poorly governed use could create durable access paths to remote infrastructure.

Credential Access

High
Category
Privilege Escalation
Content
f"chmod 600 ~/.ssh/authorized_keys && "
        f"grep -qF '{pub_key_b64}' ~/.ssh/.deepspeed_setup_marker 2>/dev/null || "
        f"(echo '{pub_key_b64}' >> ~/.ssh/.deepspeed_setup_marker && "
        f"echo '{pub_key_b64}' | base64 -d >> ~/.ssh/authorized_keys)"
    )
    print(f"Uploading public key to {host}...")
    stdout, stderr, code = sshpass_exec(host, port, password, remote_setup, timeout=15)
Confidence
99% confidence
Finding
Appending a decoded public key into ~/.ssh/authorized_keys grants future SSH access to the remote account and can function as persistence if misused. Because the skill is advertised for model training, embedding remote access establishment materially increases danger and could be abused to retain access to GPU servers after the original task.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Content
pub_key_b64 = base64.b64encode(pub_key.encode()).decode()
    remote_setup = (
        f"mkdir -p ~/.ssh && "
        f"chmod 700 ~/.ssh && "
        f"touch ~/.ssh/authorized_keys && "
        f"chmod 600 ~/.ssh/authorized_keys && "
        f"grep -qF '{pub_key_b64}' ~/.ssh/.deepspeed_setup_marker 2>/dev/null || "
        f"(echo '{pub_key_b64}' >> ~/.ssh/.deepspeed_setup_marker && "
        f"echo '{pub_key_b64}' | base64 -d >> ~/.ssh/authorized_keys)"
    )
    print(f"Uploading public key to {host}...")
    stdout, stderr, code = sshpass_exec(host, port, password, remote_setup, timeout=15)
    if code != 0:
        print(f"Public key upload failed: {stderr}")
        print(f"\nYou can add the key manually instead. Here is the public key:")
        print(f"\n--- PUBLIC KEY ---")
        print(pub_key)
        print(f"--- END ---")
        print(f"\nAfter adding, run: python3 scripts/remote_train.py check-connection")
        return
    print(f"Public key configured on remote machi
Confidence
95% confidence
Finding
The YARA hit is justified here because the code inserts an SSH key into authorized_keys, which is a classic persistence mechanism if abused. Even if intended for convenience, this pattern is dangerous in a remote-management tool because it silently expands long-term access to external systems.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill clearly describes actions that would require powerful capabilities such as shell execution, file access, environment inspection, and likely remote access, but it declares no explicit tool scope or permissions. In an agent setting, that omission weakens containment and review, making it easier for the skill to be invoked with broader-than-expected authority.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- GPU(s) or accelerator(s) with DeepSpeed-supported backend (CUDA, ROCm, Intel XPU, etc.)
- DeepSpeed: `pip install deepspeed`
- Transformers, Datasets, PEFT (for LoRA support)
- sshpass: `sudo apt-get install sshpass` (for remote training)

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

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The document establishes a hard rule that all remote operations must be dispatched through subagents, but later provides direct `exec` examples for remote setup and status actions. That inconsistency can cause implementers to bypass the intended async isolation and user-feedback model, increasing the chance of blocking behavior and unsafe direct execution of remote operations from the main agent.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The guide recommends generating an ed25519 key pair with no passphrase and frames it as the default convenience path without clearly warning the user about the risks of an unencrypted private key. If that key is stolen from the local system, an attacker can authenticate to the remote training host without needing any additional secret.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The `remote-exec` command exposes a general-purpose remote command execution primitive that goes beyond the stated fine-tuning workflow. In an agent skill context, generic remote execution materially expands the attack surface because a prompt, task description, or downstream component could invoke arbitrary commands on the remote host.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The guide recommends `--trust_remote_code true` as a troubleshooting step without warning that this allows execution of arbitrary Python code supplied by a model repository. In a fine-tuning skill that may use third-party Hugging Face models, this materially increases the risk of users running untrusted code on local or remote GPU hosts.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
2. **Multi-GPU?** Install MPI:
   ```bash
   pip install mpi4py
   sudo apt-get install -y openmpi-bin libopenmpi-dev  # Ubuntu
   pip install --force-reinstall --no-cache-dir mpi4py
   ```
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
2. **Multi-GPU?** Install MPI:
   ```bash
   pip install mpi4py
   sudo apt-get install -y openmpi-bin libopenmpi-dev  # Ubuntu
   pip install --force-reinstall --no-cache-dir mpi4py
   ```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The script exposes a trust_remote_code option and passes it to AutoTokenizer.from_pretrained and AutoModelForCausalLM.from_pretrained. In the Hugging Face ecosystem, enabling this permits execution of repository-provided Python code during model/tokenizer loading, which can run arbitrary code on the host and exceeds the expected scope of a training launcher.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
ssh_cmd = _build_ssh_base(host, port, use_key=True)
    ssh_cmd.append(cmd)
    try:
        result = subprocess.run(ssh_cmd, capture_output=True, text=True, timeout=timeout)
        if result.returncode == 0:
            return result.stdout, result.stderr, 0
    except subprocess.TimeoutExpired:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.