Back to skill

Security audit

Zhizhi Math Coach

Security checks for vulnerabilities and agentic risk

Overview

This math-coaching skill is mostly coherent, but it includes broad automatic GitHub sync, SSH/cron persistence, and an unsafe worksheet path handling bug that users should review before installing.

Install only if you are comfortable with a math skill writing local learning records and, when configured, syncing them to GitHub or publishing child-facing worksheet files. Use a private repository for full learning data, avoid enabling automatic push until you understand the commit scope, do not publish answer keys or records, and treat worksheet specs as trusted input until the path validation bug is fixed.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_worksheet.py:405
Finding
Arbitrary File Read and Write Through Unvalidated Worksheet Paths## Vulnerability Details **File Location**: `scripts/generate_worksheet.py`, lines 405–425 **Vulnerability Type**: Path traversal and unrestricted filesystem access **Risk Level**: High ### Vulnerable Code ```python out_dir = spec_path.parent worksheet_file = spec.get("worksheet_file", "worksheet.html") answer_key_file = spec.get("answer_key_file", "answer-key.md") pdf_file = args.pdf_file or spec.get("pdf_file", "worksheet.pdf") spec["worksheet_file"] = worksheet_file template_path = ROOT / spec.get("template", str(DEFAULT_TEMPLATE.relative_to(ROOT))) html_text, answers, count = render_html(spec, template_path) answer_key = render_answer_key(spec, answers, count) worksheet_path = out_dir / worksheet_file answer_key_path = out_dir / answer_key_file worksheet_path.write_text(html_text, encoding="utf-8") answer_key_path.write_text(answer_key, encoding="utf-8") print(f"generated: {worksheet_path}") print(f"generated: {answer_key_path}") print(f"items: {count}") page_config = spec.get("page", {}) verify_requested = args.verify_print or page_config.get("verify_print") pdf_requested = not args.no_pdf or args.pdf or args.pdf_file or spec.get("pdf_file") or page_config.get("pdf") pdf_required = args.pdf or args.pdf_file or spec.get("pdf_file") or page_config.get("pdf_required") or verify_requested pdf_path = out_dir / pdf_file ``` ### Technical Analysis The worksheet generator accepts `template`, `worksheet_file`, `answer_key_file`, and `pdf_file` values from a worksheet JSON specification without validating that the resulting paths remain inside approved directories. Python path joining does not provide containment. If the second operand is absolute, it replaces the intended base path. Relative values containing `../` can also traverse outside `out_dir` or `ROOT`. Consequently: - `template` can select an arbitrary readable text file and cause it to be loaded by `render_html()`. - `worksheet_file` ...[truncated 2103 chars]
Remediation
## Remediation Suggestions 1. Treat output fields as filenames rather than arbitrary paths. Reject absolute paths, `..` components, path separators, empty names, and unsupported extensions. 2. Resolve every destination and verify containment before access: ```python def contained_path(root: Path, supplied: str, allowed_suffixes: set[str]) -> Path: candidate_value = Path(supplied) if candidate_value.is_absolute() or ".." in candidate_value.parts: raise ValueError("Absolute paths and parent traversal are not allowed") candidate = (root / candidate_value).resolve() resolved_root = root.resolve() candidate.relative_to(resolved_root) if candidate.suffix.lower() not in allowed_suffixes: raise ValueError("Unsupported output extension") return candidate ``` 3. Restrict templates to an explicit allowlist under `assets/worksheet/`. Do not allow worksheet specifications to select arbitrary local files. 4. Use fixed output names such as `worksheet.html`, `answer-key.md`, and `worksheet.pdf` unless custom names are essential. 5. Account for symlink escapes by validating resolved paths immediately before each read or write. 6. Refuse to overwrite existing files by default. Require an explicit, trusted overwrite option when replacement is intended. 7. Use atomic writes through a temporary file in the validated destination directory followed by `os.replace()`. 8. Apply the same validation to `--pdf-file`, since command-line input currently reaches the vulnerable path construction. 9. Add regression tests covering absolute paths, nested traversal, symlink traversal, invalid extensions, and existing-file overwrite attempts.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (69)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill performs repository inspection, remote synchronization, commit/push actions, branch/remote management, and sync logging despite presenting itself as a child learning assistant. In this context, such behavior can leak or alter sensitive educational records and creates a supply-chain-like trust problem because users may invoke it expecting only local pedagogical assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill performs repository inspection, remote synchronization, commit/push actions, branch/remote management, and sync logging despite presenting itself as a child learning assistant. In this context, such behavior can leak or alter sensitive educational records and creates a supply-chain-like trust problem because users may invoke it expecting only local pedagogical assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill performs repository inspection, remote synchronization, commit/push actions, branch/remote management, and sync logging despite presenting itself as a child learning assistant. In this context, such behavior can leak or alter sensitive educational records and creates a supply-chain-like trust problem because users may invoke it expecting only local pedagogical assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill performs repository inspection, remote synchronization, commit/push actions, branch/remote management, and sync logging despite presenting itself as a child learning assistant. In this context, such behavior can leak or alter sensitive educational records and creates a supply-chain-like trust problem because users may invoke it expecting only local pedagogical assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill performs repository inspection, remote synchronization, commit/push actions, branch/remote management, and sync logging despite presenting itself as a child learning assistant. In this context, such behavior can leak or alter sensitive educational records and creates a supply-chain-like trust problem because users may invoke it expecting only local pedagogical assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill performs repository inspection, remote synchronization, commit/push actions, branch/remote management, and sync logging despite presenting itself as a child learning assistant. In this context, such behavior can leak or alter sensitive educational records and creates a supply-chain-like trust problem because users may invoke it expecting only local pedagogical assistance.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
If the current workspace appears to be the reusable source repository `zhizhi-math-coach-openclaw` (for example it contains `docs/openclaw-release.md` and `examples/student-workspace/`), warn before writing student learning data. Do not warn merely because a personal workspace has an installed `skills/zhizhi-math-coach/` bundle from ClawHub. Only write student data into the source repository when the user explicitly says it is the intended personal learning workspace or the task is skill development with sanitized examples.
Confidence
85% confidence
Finding
Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- Winter break should repair first-semester weak points before previewing next semester.
- Summer break should review the whole school year before previewing the next grade.

## Output Rules

When using curriculum context, state:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- Winter break should repair first-semester weak points before previewing next semester.
- Summer break should review the whole school year before previewing the next grade.

## Output Rules

When using curriculum context, state:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- `records/`, `mistakes/`, `memory/`, `weak-points/`, `knowledge-points/`, `curriculum/`;
- completed worksheet photos, school papers, textbook PDFs, scans, or OCR output.

## OpenClaw Output Rule

When Pages is configured, return the PDF file/path first, then the Pages URL when deployment is ready. Use the Pages URL in Feishu notifications when available, and send the PDF file when the channel supports file messages. Keep answer keys and diagnosis links outside published `site/` output.
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Credential Access

High
Category
Privilege Escalation
Content
## Last Resort: HTTPS Token

Use HTTPS tokens only when deploy keys or SSH are not available. The parent should create a fine-grained GitHub personal access token (PAT) scoped to the personal learning repository only.

Recommended token settings:
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## Last Resort: HTTPS Token

Use HTTPS tokens only when deploy keys or SSH are not available. The parent should create a fine-grained GitHub personal access token (PAT) scoped to the personal learning repository only.

Recommended token settings:
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Recommended token settings:

- Create path: GitHub web -> profile photo -> Settings -> Developer settings -> Personal access tokens -> Fine-grained tokens -> Generate new token.
- Token type: fine-grained personal access token.
- Resource owner: the GitHub user or organization that owns the personal learning repository.
- Repository access: `Only select repositories`, then select only the personal learning repository, such as `zhizhi-math-learning-data`.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Self-Modification

High
Category
Rogue Agent
Content
parser.add_argument("--textbook-volume", default="一年级下册")
    parser.add_argument("--textbook-index", default=DEFAULT_TEXTBOOK_INDEX)
    parser.add_argument("--timezone", default="Asia/Shanghai", help="IANA timezone for scheduled reminders, for example Asia/Shanghai.")
    parser.add_argument("--force", action="store_true", help="Overwrite existing files. Use carefully.")
    parser.add_argument(
        "--allow-source-repo",
        action="store_true",
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Self-Modification

High
Category
Rogue Agent
Content
print(f"skipped existing files: {len(skipped)}")
        for path in skipped:
            print(f"  = {path.relative_to(args.workspace)}")
        print("use --force to overwrite existing files")
    print("next: review curriculum/profile.md and memory/long-term.md, then commit from the personal repository")
    return 0
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Credential Access

High
Category
Privilege Escalation
Content
def default_key_path(owner: str, repo: str) -> Path:
    name = f"zhizhi_math_{sanitize(owner)}_{sanitize(repo)}_deploy"
    return Path.home() / ".ssh" / name


def ensure_key(key_path: Path, comment: str) -> None:
Confidence
91% confidence
Finding
The script creates a new private SSH deploy key under ~/.ssh, which is credential material even if intended for a single repository. In a skill whose stated purpose is elementary math coaching, creating persistent authentication artifacts is a sensitive capability that expands trust and attack surface if the host or skill is compromised.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The script generates SSH keys under the user's ~/.ssh directory and modifies local SSH configuration, but these capabilities are not reflected in the skill's educational description. Undisclosed credential-related behavior in a child-focused coaching skill increases the chance of stealthy persistence or unintended repository access being established without informed user understanding.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
This script provisions GitHub deploy keys, edits SSH configuration, and can repoint git remotes for repository sync, which is unrelated to a primary-school math coaching skill's declared purpose. In this context, hidden source-control and credential-management behavior is especially risky because users would not reasonably expect the skill to request or establish write-capable repository access.

Credential Access

High
Category
Privilege Escalation
Content
public_key = public_key_for(key_path)

    if not args.no_ssh_config:
        update_ssh_config(Path.home() / ".ssh" / "config", host_alias, key_path, owner, repo)

    remote_url = f"git@{host_alias}:{owner}/{repo}.git"
    if args.configure_remote:
Confidence
90% confidence
Finding
The script updates ~/.ssh/config to activate use of the generated key via a host alias, directly affecting how SSH credentials are selected on the machine. Even though this is not credential theft, it is credential-management behavior with system-wide implications and is especially suspicious given the mismatch with the skill's declared educational purpose.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
if retry.returncode == 0:
            print(retry.stdout.strip() or retry.stderr.strip() or f"ok: pushed {remote}/{branch}")
            return
        fail(detail(retry) or "git push failed after retry")

    fail(first_error or "git push failed")
Confidence
80% confidence
Finding
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).

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
This code can push committed learning records to a remote repository after task completion, and the surrounding checks explicitly contemplate syncing sensitive learning records when certain flags are set. Because the skill is for a first-grade child, the likely data includes educational history and possibly identifying student information, making remote publication especially risky if the repository is public, misconfigured, or compromised.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill instructs use of file reads/writes, shell execution, network access, and environment-dependent operations, but it does not declare any explicit tool scope or allowed-tools boundary. That creates an over-privileged execution model where a math-coaching skill can silently perform repository sync, publishing, and automation tasks beyond what a user would reasonably infer from the metadata.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
7. Explain the correction in parent-friendly language, and include a shorter student-facing version when useful.
8. Generate short validation practice for the cause, not just the surface topic.
9. Update the mistake book, progress dashboard, weak-point records, memory, and next-practice suggestion only when evidence supports it.
10. If automatic Git sync, Pages publishing, or scheduled reminders are enabled in `.zhizhi-math-coach/config.json`, sync/publish/register supported automation without asking again after local files are written.

## Expected Workspace
Confidence
90% confidence
Finding
The skill authorizes sync, publish, and automation actions 'without asking again' once config flags are enabled. Durable consent can be reasonable for low-risk local writes, but here it governs network transfer, publication, and cron registration, so repeated side effects may occur without contextual confirmation when a task is invoked.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill instructs automatic writes, sync, publishing, and cron registration without an upfront warning in the user-facing description. That weakens informed consent and makes it easier for a benign-looking educational skill to perform persistent or networked side effects a user may not anticipate.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- `scripts/prepare_github_deploy_key.py`: generate a repository-scoped SSH deploy key and public-key setup instructions for GitHub Deploy keys.
- `scripts/setup_github_pages_workflow.py`: create `.github/workflows/pages.yml` for publishing `site/` through GitHub Actions.
- `scripts/setup_scheduled_tasks.py`: enable automation config and register OpenClaw cron reminder jobs when `openclaw cron` is available.
- `scripts/sync_learning_repo.py`: pull, commit, and push configured learning-data changes without asking again when automatic sync is enabled.
- `references/daily-grading-workflow.md`: fast grading, light recording, automatic full-archive upgrade, subagent boundary, validation, recording, and grading sync.
- `scripts/build_grading_context.py`: build one compact grading context from config, active context, and curriculum profile.
- `scripts/validate_diagnosis_payload.py`: validate diagnosis JSON before writing records.
Confidence
88% confidence
Finding
The referenced scripts explicitly support deploy-key prep, workflow creation, cron registration, and git sync without asking again, reinforcing autonomous side effects in a skill that handles sensitive child learning data. This increases the chance of unintended persistence or exposure if the workspace/config is wrong or stale.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/validate_worksheet_spec.py:29