T09 · Insecure Skill Coding Practices
- Location
ssh-manager.en.html:360- Finding
Shell Command Injection Through Web UI Configuration Serialization
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This SSH management skill is mostly purpose-aligned, but it installs a persistent network service and handles SSH credentials and server access with unsafe scoping that users should review carefully.
Install only if you intend to grant this skill administrative control over SSH access on the configured servers. Review the post-install service first, prefer disabling the auto-start web service, bind any UI to loopback only, avoid password-based SSH where possible, verify host keys, and test on non-production targets before using enable-all or disable-all.
ssh-manager.en.html:360Shell Command Injection Through Web UI Configuration Serialization
ssh-manager.en.html:174Stored Cross-Site Scripting in the Privileged Server List
${server.user}@${server.host}
${server.user}
${server.host}:${server.port || 22}
${server.auth === 'key' ? '🔑 Key' : '🔒 Password'}
Configured
Enable
Disable
Delete
`).join('');
}
```
### Technical Analysis
Configuration values are inserted directly into `innerHTML` and inline event-handler attributes without HTML or JavaScript-context escaping. A crafted `server.user`,
...[truncated 1580 chars]serve-ui.py:39Web UI Server Exposed on All Network Interfaces Without Authentication
post-install.sh:33Automatic Installation of a System-Wide Persistent Web Service
ssh-batch-manager.py:181SSH Host Authentication Disabled During Credentialed Operations
ssh-batch-manager.py:782Sensitive Passwords and Encryption Keys Exposed Through Process Arguments and Standard Output
Appending a key to ~/.ssh/authorized_keys is a credential and persistence action because it modifies who can authenticate to the account. In this context the feature is intentional, but if the wrong key, host, or account is targeted, it silently establishes durable remote access across systems.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}" cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
**效果**:
The YARA rule matched because the documented command performs SSH key injection into authorized_keys, a classic persistence mechanism also used by attackers. Even though the apparent product intent is legitimate batch administration, the exact behavior is security-sensitive and especially dangerous here because the changelog shows use on multiple production servers and root accounts.
�能免密登录,跳过
---
### 2️⃣ 来源标识
**问题**: 无法区分公钥是从哪台服务器分发的。
**解决**: 在 authorized_keys 中添加来源标识注释。
**实现**:
```python
SOURCE_IDENTIFIER = "ssh-batch-manager"
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
效果:
# authorized_keys 内容
ssh-ed25519 AAAAC3... ssh-batch-manager from mls at 2026-03-03 17:30:00
优势:
问题: 测试配置和生产配置混在一起。
解决: 删除测试服务器,只保留生产服务器。
清理的服务器:
保留的服务器:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}" cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}" cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}" cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
```
**Effect**:
Appending directly to ~/.ssh/authorized_keys is a persistence mechanism and is inherently high risk because it grants or maintains SSH access on remote systems. In this skill's context, that behavior is the advertised purpose, which makes it less indicative of malware intent, but the shell-based construction shown is still dangerous because misuse, mis-targeting, or command injection through unescaped key/comment data could lead to unauthorized access or account compromise across multiple servers.
g
---
#### 2️⃣ Source Identifier
**Problem**: Cannot distinguish which server distributed the public key.
**Solution**: Add source identifier comment to authorized_keys.
**Implementation**:
```python
SOURCE_IDENTIFIER = "ssh-batch-manager"
SOURCE_HOST = subprocess.run(['hostname'], ...).stdout.strip()
source_comment = f" {SOURCE_IDENTIFIER} from {SOURCE_HOST} at {timestamp}"
cmd = f'echo "{pub_key}{source_comment}" >> ~/.ssh/authorized_keys'
Effect:
# authorized_keys content
ssh-ed25519 AAAAC3... ssh-batch-manager from mls at 2026-03-03 17:30:00
Benefits:
Problem: Test and production configurations mixed together.
Solution: Delete test servers, keep only production servers.
Deleted servers:
Retained servers:
If the skill primarily launches a local web UI and does not actually perform multi-server SSH management, connectivity checks, or source tracking, the mismatch is severe because it misrepresents both functionality and risk. Such deception can cause users to expose credentials and install persistence without obtaining the promised security or operational benefit.
If the skill primarily launches a local web UI and does not actually perform multi-server SSH management, connectivity checks, or source tracking, the mismatch is severe because it misrepresents both functionality and risk. Such deception can cause users to expose credentials and install persistence without obtaining the promised security or operational benefit.
If the skill primarily launches a local web UI and does not actually perform multi-server SSH management, connectivity checks, or source tracking, the mismatch is severe because it misrepresents both functionality and risk. Such deception can cause users to expose credentials and install persistence without obtaining the promised security or operational benefit.
If the skill primarily launches a local web UI and does not actually perform multi-server SSH management, connectivity checks, or source tracking, the mismatch is severe because it misrepresents both functionality and risk. Such deception can cause users to expose credentials and install persistence without obtaining the promised security or operational benefit.
If the skill primarily launches a local web UI and does not actually perform multi-server SSH management, connectivity checks, or source tracking, the mismatch is severe because it misrepresents both functionality and risk. Such deception can cause users to expose credentials and install persistence without obtaining the promised security or operational benefit.