T09 · Insecure Skill Coding Practices
- Location
commands/dev_flow.py:67- Finding
Failed tests or security scans do not prevent publication
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a plausible lifecycle automation tool, but its release workflow can publish after failed checks and its normal Git flow can commit unrelated or sensitive files.
Review carefully before installing. Use this only in disposable or well-controlled repositories, prefer dry-run first, inspect git status before any workflow, avoid running full publishing until the release-gate bug is fixed, and pin dependencies in an isolated virtual environment.
commands/dev_flow.py:67Failed tests or security scans do not prevent publication
commands/git_ops.py:59Automatic blanket Git staging can commit unrelated or sensitive files
commands/quality.py:50Security scanner ignores nested and non-Python content while reporting success
requirements.txt:2Open-ended dependency versions prevent reproducible, integrity-verified installation
The description claims a broad end-to-end lifecycle tool covering versioning, testing, quality scanning, Git submission, and optional publishing/knowledge extraction. However, this code chunk only provides a CLI for configuration file management. It reads/writes YAML config files, validates required keys, shows config values, and attempts to open the config in an editor. While these settings reference versioning, scan, test, git, and publish options, the code does not actually execute those workflows. This is therefore a material description-to-behavior mismatch: the actual primary behavior is config management, which is only a supporting subset of the declared lifecycle tool.
The code substantially matches the declared core workflow: version management, testing, quality scan, and Git commit are all implemented, and optional ClawHub publishing is also present in full_flow. However, the declaration also claims an optional '知识提炼' (knowledge extraction) capability, which is not implemented anywhere in the provided code. Additionally, while the description presents a full lifecycle management tool, this file's default executable entrypoint runs only the development flow without publishing; the full flow exists but is a separate command. This is a partial mismatch rather than a complete one, because most of the declared functionality is represented.
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).
@click.command()
@click.argument('skill_dir', default='.', type=click.Path(exists=True))
@click.option('--bump', type=click.Choice(['major', 'minor', 'patch']), help='版本升级类型')
@click.option('--skip-test', is_flag=True, help='跳过测试')
@click.option('--skip-scan', is_flag=True, help='跳过质量扫描')
@click.option('--dry-run', is_flag=True, help='预览不执行')
def dev_flow(skill_dir, bump, skip_test, skip_scan, dry_run):
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).
@click.command()
@click.argument('skill_dir', default='.', type=click.Path(exists=True))
@click.option('--bump', type=click.Choice(['major', 'minor', 'patch']), help='版本升级类型')
@click.option('--skip-test', is_flag=True, help='跳过测试')
@click.option('--skip-scan', is_flag=True, help='跳过质量扫描')
@click.option('--dry-run', is_flag=True, help='预览不执行')
def dev_flow(skill_dir, bump, skip_test, skip_scan, dry_run):
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).
@click.command()
@click.argument('skill_dir', default='.', type=click.Path(exists=True))
@click.option('--bump', type=click.Choice(['major', 'minor', 'patch']), help='版本升级类型')
@click.option('--skip-test', is_flag=True, help='跳过测试')
@click.option('--skip-scan', is_flag=True, help='跳过质量扫描')
@click.option('--dry-run', is_flag=True, help='预览不执行')
def dev_flow(skill_dir, bump, skip_test, skip_scan, dry_run):
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).
@click.command()
@click.argument('skill_dir', default='.', type=click.Path(exists=True))
@click.option('--bump', type=click.Choice(['major', 'minor', 'patch']), help='版本升级类型')
@click.option('--skip-test', is_flag=True, help='跳过测试')
@click.option('--skip-scan', is_flag=True, help='跳过质量扫描')
@click.option('--dry-run', is_flag=True, help='预览不执行')
def dev_flow(skill_dir, bump, skip_test, skip_scan, dry_run):
The skill advertises and demonstrates shell execution plus file read/write behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. This weakens containment and review because an invoking agent may grant broader capabilities than users expect, especially for commands that modify repositories and local files.
Broad trigger phrases increase the chance that the skill is invoked unintentionally in conversations about generic lifecycle, automation, or version-management topics. Because this skill can lead to shell commands, file changes, Git commits, and optional publishing, accidental invocation could cause unintended state changes or nudge an agent toward risky actions.
The documented scenarios encourage development and release workflows but do not warn users that Git operations and publishing can change external state. In a lifecycle automation context, missing warnings are especially risky because users may treat the skill as a harmless helper while it can commit code or publish artifacts.
This file's user-facing natural language strings, including the top-level docstring and command/help text, are entirely in Chinese, with no indication that language is selectable or that the tool is intentionally region-specific. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.
This Python file contains docstrings, prompts, and console output in Chinese only, including confirmation and error messages. Under the language/locale policy rule, forcing a single language without user opt-in is a natural-language policy concern unless the tool is clearly documented as region-specific, which is not evident in this file.
At L133 the comment says the code will use the default editor, and L135's inline comment says it is obtaining the system default editor. In reality, subprocess._optim_args_from_interpreter_flags() returns interpreter optimization flags, not an editor command, so the documented intent directly contradicts the actual behavior of the code.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
editor = subprocess._optim_args_from_interpreter_flags() # 获取系统默认编辑器
try:
subprocess.run([editor, str(config_path)])
console.print("[green]✅ 配置已保存[/green]")
except Exception as e:
console.print(f"[red]❌ 编辑失败:{e}[/red]")
The file's docstrings, CLI help text, and runtime console messages are written exclusively in Chinese, which imposes a specific language on users. The policy allows locale constraints only when users are given a choice or the restriction is clearly documented and justified, neither of which appears here.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 检查是否在 Git 仓库中
try:
result = subprocess.run(
['git', 'rev-parse', '--git-dir'],
cwd=skill_dir,
capture_output=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 显示变更
console.print("\n[bold]待提交的变更:[/bold]")
result = subprocess.run(
['git', 'status', '--short'],
cwd=skill_dir,
capture_output=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 显示变更
console.print("\n[bold]待提交的变更:[/bold]")
result = subprocess.run(
['git', 'status', '--short'],
cwd=skill_dir,
capture_output=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 添加变更
if auto_add:
console.print("\n[bold]添加所有变更...[/bold]")
subprocess.run(['git', 'add', '-A'], cwd=skill_dir, check=True)
# 提交
console.print(f"\n[bold]提交:{message}[/bold]")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 提交
console.print(f"\n[bold]提交:{message}[/bold]")
result = subprocess.run(
['git', 'commit', '-m', message],
cwd=skill_dir,
capture_output=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if result.returncode == 0:
# 获取提交 hash
result_hash = subprocess.run(
['git', 'rev-parse', '--short', 'HEAD'],
cwd=skill_dir,
capture_output=True,
This file contains natural-language strings such as the module docstring, option help text, and console output exclusively in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 2. 检查 ClawHub 是否可用
try:
result = subprocess.run(
['clawhub', '--help'],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.extend(['--changelog', changelog])
try:
result = subprocess.run(
cmd,
cwd=skill_dir,
capture_output=True,
This Python file uses natural-language strings exclusively in Chinese, starting with the module docstring at L002 and continuing throughout user-facing CLI messages. The file does not offer a language choice or explain that the tool is intentionally region-specific, which can violate the policy against forcing a specific language without user opt-in.
This Python file uses natural-language text exclusively in Chinese in the module docstring, and the same locale-specific wording continues throughout user-visible issue messages. For a general-purpose quality scanning skill, this imposes a language choice without any opt-in or documented regional justification, which matches the locale-policy violation criteria.
No suspicious patterns detected.