T09 · Insecure Skill Coding Practices
- Location
main.py:66- Finding
Shell Command Injection Through MCP Command Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This memory-sync skill has a legitimate purpose, but it broadly handles private memories and includes unsafe install, cleanup, credential, and command execution behavior that needs review before use.
Install only after reviewing and narrowing what channels and memories it may read, store, export, and delete. Avoid running the installer with sudo, do not enable cron cleanup until backups and dry-run behavior are confirmed, keep API keys out of source files, and use local-only or redacted validation for sensitive memories.
main.py:66Shell Command Injection Through MCP Command Arguments
install.sh:52Installer Persistently Modifies Shell Profiles and Attempts a Privileged System-Wide Symlink
setup_env.sh:18Unpinned Runtime Dependency Installation From the Ambient Package Index
configs/settings_loader.py:63API Key Can Be Embedded as Plaintext in a Python Source File
core/triple_agent_processor.py:243Callable Validation Processor Sends Complete Memory Content to an External Cloud Provider Without Redaction
The README explicitly promotes automatic collection and unified storage of conversations from multiple channels, but provides no meaningful privacy notice, consent flow, retention guidance, or scoping limits. In a memory-sync skill, this creates a real risk of silently aggregating sensitive personal, business, or regulated communications into a central store, increasing exposure and compliance risk.
The zero-config and auto-start instructions encourage immediate activation of syncing across all enabled channels without any consent checkpoint or privacy review. This is especially dangerous in an agent skill because users may enable it expecting convenience, while the skill begins broad collection of historical and ongoing conversations by default.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
### 测试 2:路径遍历
**操作**: 尝试使用 `../../../etc/passwd` 作为路径
**结果**: 正常存储为路径字符串(不实际访问文件系统)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
│ └── ... ├── configs/ # 配置文件 ├── prompts/ # 提示词模板 └── .env # 环境变量配置
## 🔧 使用说明
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
else:
raise FileNotFoundError(f"Prompt 文件不存在:{prompt_file}")
return prompts
def _init_configs(self):
"""初始化模型配置 - 使用 Kimi API"""
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
else:
raise FileNotFoundError(f"Prompt 文件不存在:{prompt_file}")
return prompts
def _init_configs(self):
"""初始化模型配置 - 使用 Kimi API"""
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
else:
raise FileNotFoundError(f"Prompt 文件不存在:{prompt_file}")
return prompts
def _init_configs(self):
"""初始化模型配置 - 使用 Kimi API"""
The script performs destructive deletion of stored memories automatically, without confirmation, dry-run mode, approval gating, or rollback support. In this context, a faulty heuristic, compromised local API, or malformed duplicate grouping could cause irreversible loss of user or system data at scale.
The code exports parsed memory contents and the entire user profile into a shared directory under the user's home folder without any consent, access control, minimization, or masking. Because these files appear to contain personal preferences, profile data, and potentially sensitive system memories, this creates a clear confidentiality risk through unintended cross-process or cross-tool data exposure.
The export logic intentionally packages all 'important' memories plus the full user profile into a JSON file in a shared folder, which materially broadens data exposure beyond the original Hermes storage boundary. In an agent-skill context, where memory files may contain secrets, behavioral history, or personal data, this increases the chance of unauthorized access by other tools, plugins, or local users/processes.
The YARA hit is triggered by persistent modification of shell startup files via alias injection. In this context it does not look like a malware backdoor because the alias points to the advertised CLI, but the technique is still security-relevant because rc-file persistence is a common stealth mechanism and can surprise users or be repurposed if the target script changes later.
ync/shared_memory_cli.py
# 创建符号链接(可选)
echo "🔗 创建命令行快捷方式..."
if [ ! -f /usr/local/bin/shared-memory-sync ]; then
sudo ln -sf ~/.hermes/skills/openclaw-imports/memory-plus-sync/shared_memory_cli.py /usr/local/bin/shared-memory-sync 2>/dev/null || \
echo "⚠️ 无法创建系统级符号链接,使用本地别名"
# 创建本地别名
echo "alias shared-memory-sync='python3 ~/.hermes/skills/openclaw-imports/memory-plus-sync/shared_memory_cli.py'" >> ~/.bashrc 2>/dev/null || true
echo "alias shared-memory-sync='python3 ~/.hermes/skills/openclaw-imports/memory-plus-sync/shared_memory_cli.py'" >> ~/.zshrc 2>/dev/null || true
fi
# 创建定时任务配置
echo "⏰ 创建定时任务配置..."
CRON_CONFIG="# 共享记忆同步系统定时任务
# 每小时同步一次
0 * * * * cd ~/.hermes/skills/openclaw-imports/memory-plus-sync && python3 shared_memory_cli.py sync-bidirectional
# 每天凌晨2点清理记忆
0 2 * * * c
The mcp command constructs a shell command with untrusted CLI arguments using os.system and string concatenation. Any attacker-controlled argument in sys.argv[2:] can inject additional shell metacharacters and execute arbitrary commands in the user's environment.
elif command == "mcp":
# 启动 MCP 服务器
os.system(f"python {Path(__file__).parent}/mcp_server.py {' '.join(sys.argv[2:])}")
elif command == "test":
# 运行测试
os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.
# 运行测试
test_script = Path(__file__).parent / "test_full_workflow.py"
if test_script.exists():
os.system(f"python {test_script}")
else:
print("⚠️ 测试脚本未找到")
The database cleanup path performs a DELETE against persistent records based solely on age, with no user confirmation, preview, transaction rollback option, or safety checks around schema/record scope. In a skill context this is more dangerous because the operation can silently destroy stored memory data at scale, and a user may trigger it indirectly without realizing it includes destructive database deletion.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# 生成环境配置文件
echo ""
echo "6. 生成环境配置文件..."
ENV_FILE="$HOME/.hermes/skills/openclaw-imports/memory-plus-sync/.env"
cat > "$ENV_FILE" << EOF
# Memory Plus Sync 2.0 环境配置
# 生成时间: $(date)
The slogan combined with zero-config automatic sync signals a default behavior of retaining all user conversations, which is an unsafe data-retention posture for a memory product. In context, this normalizes indiscriminate storage and can lead users to unknowingly persist sensitive prompts, credentials, personal data, or confidential discussions.
The README advertises automatic repair behavior, and elsewhere mentions maintenance actions like VACUUM optimization and FTS index rebuild, but does not warn about possible data loss, locking, downtime, or state changes. Destructive or state-altering maintenance without explicit caution is a real safety issue because operators may enable it in production without understanding the impact.
The language encourages broad automatic collection and centralization of conversations across platforms, which materially increases semantic privacy leakage risk even if no direct exfiltration is described. Aggregating messages from Feishu, WeChat, Telegram, and voice into one searchable memory store can expose sensitive context that was originally compartmentalized by channel.
The README presents cleanup operations that delete or rewrite memory data as routine commands without placing a prominent warning directly at the point of use. In a skill that manages persistent memories and databases, users may run cleanup commands assuming they are safe maintenance steps, causing unintended irreversible loss or corruption of stored data.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
cat ~/.shared-memory/cron_config.txt
# 添加到 crontab
crontab -e
# 添加以下内容:
# 每小时同步一次
0 * * * * cd ~/.hermes/skills/openclaw-imports/memory-plus-sync && python3 shared_memory_cli.py sync-bidirectional
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
cat ~/.shared-memory/cron_config.txt
# 添加到 crontab
crontab -e
# 添加以下内容:
# 每小时同步一次
0 * * * * cd ~/.hermes/skills/openclaw-imports/memory-plus-sync && python3 shared_memory_cli.py sync-bidirectional
The cron examples automate cleanup and full-workflow jobs that alter databases and delete old files, but the README does not clearly warn that unattended scheduled execution will perform destructive changes continuously. Because this system operates on long-lived memory stores, automation materially increases the chance of silent data loss, propagation of bad state, or repeated deletion before a user notices.
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.
# Hermes 同步日志
ls -la ~/.shared-memory/hermes/logs/
# OpenClaw 同步日志
ls -la ~/.shared-memory/openclaw/logs/
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.
# Hermes 同步日志
ls -la ~/.shared-memory/hermes/logs/
# OpenClaw 同步日志
ls -la ~/.shared-memory/openclaw/logs/
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.
# Hermes 同步日志
ls -la ~/.shared-memory/hermes/logs/
# OpenClaw 同步日志
ls -la ~/.shared-memory/openclaw/logs/
No suspicious patterns detected.