T09 · Insecure Skill Coding Practices
- Location
scripts/add_skill.py:31- Finding
Security Vetting Results Are Ignored and Replaced with a Hard-Coded Passing Score
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill manages other skills, but its advertised safety gate is ineffective and its recommended automation can change installed skills without timely review.
Review this skill before installing. Use manual or dry-run workflows first, avoid running it from cron or as root, and do not rely on its trust scores as real security results until vetting output, update verification, and approval controls are fixed.
scripts/add_skill.py:31Security Vetting Results Are Ignored and Replaced with a Hard-Coded Passing Score
scripts/apply_updates.py:38Unattended Remote Updates Depend on Unverified and Mutable Trust Metadata
scripts/auto_run.py:12Scheduled Workflow Uses Unnecessary Shell Interpretation for Path-Based Commands
The documentation presents broad security-management capabilities, including version tracking and protection against risky updates, but the provided file alone does not evidence those features. Because the skill is positioned as a defensive control, any gap between promise and reality increases operational risk through misplaced trust and over-automation.
The documentation presents broad security-management capabilities, including version tracking and protection against risky updates, but the provided file alone does not evidence those features. Because the skill is positioned as a defensive control, any gap between promise and reality increases operational risk through misplaced trust and over-automation.
The documentation presents broad security-management capabilities, including version tracking and protection against risky updates, but the provided file alone does not evidence those features. Because the skill is positioned as a defensive control, any gap between promise and reality increases operational risk through misplaced trust and over-automation.
The documentation presents broad security-management capabilities, including version tracking and protection against risky updates, but the provided file alone does not evidence those features. Because the skill is positioned as a defensive control, any gap between promise and reality increases operational risk through misplaced trust and over-automation.
The code claims to perform security vetting, but it ignores the subprocess result and always returns passed=True with a hardcoded trust score of 80 unless an exception is thrown. This creates a false sense of safety and allows unvetted or malicious skills to enter the workflow under the appearance of having passed security checks.
Skill addition is gated only on the vet_result['passed'] flag, but that flag is effectively always true because vet_skill does not enforce real vetting. In a skill-management system whose purpose is to protect users from risky additions and updates, this undermines the core security control and permits unsafe skills to be queued and later activated.
This is a true tool-parameter abuse issue because shell=True hands the full command string to a shell, enabling shell metacharacter interpretation. In a skill-management tool that automatically discovers, updates, and executes maintenance tasks on a schedule, this is more dangerous than usual: any attacker influence over script paths, environment, or future command composition could turn routine auto-runs into arbitrary command execution.
print(f"📋 {description}")
print('='*50)
try:
result = subprocess.run(
cmd,
shell=True,
capture_output=False,
The skill documentation instructs users to run Python scripts and set up cron automation, which implies shell execution and likely file modification behavior, but the manifest declares no explicit tool scope such as allowed-tools or permissions. This creates a transparency and least-privilege problem: users and platforms cannot clearly evaluate or constrain the skill's operational capabilities before installation.
The skill advertises automatic promotion of new skills and automatic application of updates without a prominent warning that these actions can modify the user's installed skill set. Unattended changes to executable skill inventory are security-relevant and can introduce new code or altered behavior without timely human review.
The documentation recommends cron-based unattended execution of workflows that include processing pending skills and applying updates, but it does not clearly warn that scheduled runs may make autonomous changes. In the context of software/skill management, silent background modification substantially raises supply-chain and persistence risk because updates may be installed when the user is absent.
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.
# Edit crontab
crontab -e
# Add lines for morning (8am) and evening (8pm) runs
0 8 * * * cd /root/.openclaw/workspace && python3 skills/skill-guardian/scripts/auto_run.py >> logs/skill-guardian.log 2>&1
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.
# Edit crontab
crontab -e
# Add lines for morning (8am) and evening (8pm) runs
0 8 * * * cd /root/.openclaw/workspace && python3 skills/skill-guardian/scripts/auto_run.py >> logs/skill-guardian.log 2>&1
The documentation explicitly recommends running scripts that automatically check for and apply updates, including apply_updates.py --all, without any warning that these operations can modify installed skills or local state. In a security-focused skill, encouraging unattended state-changing actions increases the chance of silent installation of unwanted or compromised updates, especially when triggered by cron.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def vet_skill(skill_name):
"""Run skill-vetter security check."""
try:
result = subprocess.run(
["python3", "skills/skill-vetter/scripts/vet.py", skill_name],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f"🔄 Updating {skill_name} to {info['latest_version']}...")
try:
subprocess.run(
["clawhub", "update", skill_name, "--version", info["latest_version"]],
check=True,
timeout=120
The script executes shell commands via subprocess.run with shell=True, which makes command interpretation dependent on the shell rather than a fixed argv list. Although the current command strings are internally constructed, they embed a filesystem path (SCRIPT_DIR) and create an unnecessary command-injection surface if the path or invocation context is attacker-controlled, especially in a scheduled automation script that applies updates.
print(f"📋 {description}")
print('='*50)
try:
result = subprocess.run(
cmd,
shell=True,
capture_output=False,
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
def auto_run():
"""Execute the full auto-guardian workflow."""
print("🛡️ Skill Guardian Auto-Run")
print(f"⏰ Started at: {__import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
results = []
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
status = "✅" if success else "⚠️"
print(f"{status} {name}")
print(f"\n⏰ Completed at: {__import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
return all(r[1] for r in results)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def get_latest_version(skill_name):
"""Query clawhub for latest version."""
try:
result = subprocess.run(
["clawhub", "list"],
capture_output=True,
text=True,
Line L05 uses the Chinese term '推荐' in an otherwise English-language document. This imposes a locale/language choice without user opt-in and may violate organizational language consistency expectations.
This code writes the skill registry JSON to disk, which is a persistent modification to user or project data. While the script prints status messages elsewhere, there is no disclosure at the write site or documented warning in this file that running the command will modify the registry file.
No suspicious patterns detected.