T09 · Insecure Skill Coding Practices
- Location
script/commit.py:23- Finding
Repository-Wide Staging Includes Files Excluded from Analysis
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is not clearly malicious, but its commit workflow can stage and commit more repository files than it analyzes or shows to the user.
Review before installing if you want strict control over commits. Use it only in repositories where staging every eligible file is acceptable, and inspect `git status` carefully before confirming. Avoid using it around secrets, local config files, generated artifacts, or unrelated changes until the workflow stages only explicitly reviewed paths and checks Git command failures.
script/commit.py:23Repository-Wide Staging Includes Files Excluded from Analysis
script/analyze.py:22Substring-Based Attribution Markers Allow Contribution Statistics to Be Manipulated
script/commit.py:23Unchecked Git Operations Produce False Success Reports and Leave Partial State
The skill prescribes running commit-related commands and completing a repository-modifying workflow without requiring a clear user warning or explicit final confirmation. Because commits alter project history and may trigger downstream automation, silent or insufficiently disclosed execution can lead to integrity issues, accidental changes, or abuse in multi-step conversations.
The document is written as a mandatory instruction set in Chinese and defines the assistant role and required outputs without offering any language choice. This imposes a locale/language constraint on all interactions and output, which matches the policy category for forced language without user opt-in.
文档在 L038-L040 明确规定“仅统计非空行”“注释行计入”“标记行计入”,但实现中在遇到 "@human" 或 "@ai" 时直接切换状态并 continue,因此这些标记行不会增加 total。这里不是文档遗漏,而是统计口径与代码实现直接矛盾,会导致生成的 AI 占比与技能宣称的规范不一致。
L088-L097 要求提交类型、说明、版本号、模块名称缺失时必须重新询问,但 ai_commit.py 在 L262-L265 只调用 input 读取一次,未检查空字符串,也未循环补问。代码因此允许缺失关键信息的提交继续进入统计和确认流程,与文档的强制交互要求相矛盾。
The skill directs automatic execution of a commit workflow that stages all repository changes via git add . and then commits them, without an explicit warning or narrow scoping. In an agent-assisted context, this can cause unintended inclusion of sensitive files, secrets, or unrelated modifications, especially when the user only intended to commit a subset of changes.
L330-L334 将“无代码变更”定义为必须处理的异常场景并指定输出,但 analyze_all 仅在无文件或 total_sum 为 0 时返回 0 值,ai_commit.py 随后仍会打印统计结果并进入确认提交流程。代码没有按文档要求中止或输出指定异常信息,属于明确的意图与实现不一致。
The skill directs the agent to read repository state and execute shell commands such as Python and Git, but it does not declare any explicit tool scope or allowed-tools policy. This creates an overbroad execution surface where a host agent may permit more capabilities than intended, increasing the chance of unauthorized file access or command execution.
The trigger condition uses broad language like '提交代码' or similar semantics, which can match ordinary conversation and cause the agent to enter a commit workflow unexpectedly. In a skill that culminates in repository-modifying actions, ambiguous intent detection raises the risk of accidental command execution and unintended commits.
The section states that Python should be executed via python -c and explicitly says not to create Python source files, yet the skill earlier defines and invokes script files such as script/analyze.py and script/ai_commit.py. This is an active contradiction in the documented operating model, not merely an omission.
This code presents all interactive prompts and status messages exclusively in Chinese, which imposes a specific language on users without opt-in. Under the policy, language constraints should either offer user choice or be clearly documented as intentionally locale-specific.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def get_changed_files():
try:
output = subprocess.check_output(
["git", "diff", "--name-only"],
text=True
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
from collections import defaultdict
def get_logs():
return subprocess.check_output(
["git", "log", "--pretty=format:%B||END||"],
text=True,
errors="ignore"
The regex patterns require commit messages to use Chinese labels such as 提交人:, 版本:, and 代码总行数:. This enforces a specific language convention in natural-language content without any visible opt-in, fallback, or documented locale justification.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def get_git_user():
try:
return subprocess.check_output(
["git", "config", "user.name"], text=True
).strip()
except:
This call stages all repository changes via git add ., which can unintentionally include unrelated, sensitive, or generated files in a commit. In an agent skill context, automatically modifying repository state without explicit user confirmation increases the risk of accidental data disclosure or unauthorized changes.
AI代码总行数:{ai}
AI代码占比:{percent}%"""
subprocess.run(["git", "add", "."])
subprocess.run(["git", "commit", "-m", commit_msg])
return commit_msg
The skill is described as a code marking/statistics tool, but it also performs repository-modifying Git operations. This mismatch makes the behavior more dangerous because users may invoke the skill expecting analysis only, while it silently changes repository history and staged content.
The file executes staging and commit subprocesses without any user-facing warning, preview, or confirmation. In an agent environment, silent repository mutation is risky because it can commit sensitive files, incomplete work, or attacker-influenced content with little visibility to the user.
This call performs git commit automatically using a generated message, causing a persistent repository modification without any approval gate. Even though arguments are passed safely as a list, the security issue is the side effect: an agent can create commits that record unintended content or metadata in version history.
AI代码占比:{percent}%"""
subprocess.run(["git", "add", "."])
subprocess.run(["git", "commit", "-m", commit_msg])
return commit_msg
L338-L342 规定统计失败时应输出明确错误信息,但 analyze.py 的 get_changed_files 和 analyze_file 在 L176-L199 使用裸 except 并返回空列表或忽略失败,最终可能只得到 0 统计而不是失败提示。该实现掩盖统计异常,使用户无法区分“无变更”和“统计失败”。
The code invokes git log via subprocess.check_output, which is a subprocess execution. In this file there is no confirmation prompt, logging, print statement, or explanatory comment/docstring disclosing that an external command will be run.
The generated commit message forces Chinese field labels such as 提交人 and 版本, which imposes a specific language choice on all users. There is no indication of user opt-in, configurability, or documented locale-specific scope that would justify the restriction.
No suspicious patterns detected.