Back to skill

Security audit

Weixin Task Workbench

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its task-management purpose, but its registry code can silently copy task data and session keys across WeChat account boundaries.

Install only after the publisher removes or makes explicit the cross-account registry restoration behavior, ensures registry operations stay within the active account/contact path, and redacts or gates sessionKey and raw path diagnostics. The session-tool requirements are understandable for this workflow, but they should be paired with strict ownership checks and narrow filesystem scope.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/task_registry.py:134
Finding

Cross-Account Registry Disclosure and Session-Boundary Contamination

Content
View full analysis

Vulnerability Details

File Location: scripts/task_registry.py:134-163, 178-188
Vulnerability Type: Cross-account access-control violation
Risk Level: High

Vulnerable Code

python
def find_cross_account_candidates(path: Path) -> list[Path]:
    try:
        account_dir = path.parent
        root = account_dir.parent
        peer_name = path.name
    except Exception:
        return []
    if not root.exists():
        return []
    candidates = []
    peer_aliases = {p.name for p in alias_registry_paths(path)}
    for other_account_dir in root.iterdir():
        if not other_account_dir.is_dir() or other_account_dir == account_dir:
            continue
        for peer_alias in peer_aliases:
            candidate = other_account_dir / peer_alias
            if candidate.exists():
                candidates.append(candidate)
    return sorted(set(candidates))


def restore_cross_account_registry(path: Path, data: dict) -> tuple[dict, list[str]]:
    restored_from = []
    merged = data
    for candidate in find_cross_account_candidates(path):
        other = load_json_file(candidate)
        if not other or not other.get("tasks"):
            continue
        if not merged.get("tasks") or len(other.get("tasks", [])) > len(merged.get("tasks", [])):
            merged = merge_registries(other, merged)
            restored_from.append(str(candidate))
    return merged, restored_from

The cross-account restoration is invoked automatically when a registry does not exist or contains no tasks:

python
def load_registry(path: Path) -> dict:
    resolved = choose_registry_path(path)
    if not resolved.exists():
        data = default_registry()
        data, restored_from = restore_cross_account_registry(path, data)
        save_registry(path, data)
        if restored_from:
            data["_restoredFrom"] = restored_from
        return data
    data = load_json_file(resolved) or default_registry()
    restored_from = []
    if not data.
...[truncated 3056 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove automatic cross-account discovery and restoration:

    • Delete or disable find_cross_account_candidates().
    • Delete or disable restore_cross_account_registry().
    • Ensure load_registry() only reads the exact registry path for the current account and peer.
  2. Preserve strict namespace isolation:

    • Resolve and normalize the registry path.
    • Verify that the resolved path remains under the expected tasks/weixin/<account> directory.
    • Reject traversal components, symbolic-link escapes, and paths outside the assigned account namespace.
  3. Treat migration as a privileged operation:

    • If cross-account migration is a legitimate requirement, implement it as an explicit administrative command.
    • Require authorization for both the source and destination accounts.
    • Display the source, destination, and records to be migrated before confirmation.
    • Maintain an audit log rather than silently importing data.
  4. Validate session ownership before use:

    • Bind each stored session key to its creating account and peer.
    • Before calling sessions_history or sessions_send, verify that the session belongs to the active account/peer.
    • Do not rely solely on possession of a session key as authorization.
    • Prefer restricted session visibility over sessions.visibility=all.
  5. Avoid copying foreign identifiers:

    • Never merge session keys across account namespaces.
    • If task metadata must be migrated, create new destination sessions and exclude source session identifiers.
  6. Add regression tests that verify:

    • A missing registry does not inspect sibling account directories.
    • An empty registry remains empty rather than importing another account's tasks.
    • Identical peer names under different accounts remain isolated.
    • A session key created for one account is rejected when used from another.
    • Registry aliases are confined to the current account directory.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 222)May include surrounding context.

md
- `SKILL.md`

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill directs use of python3 scripts/task_registry.py to read and modify registry files under tasks/weixin/..., which implies file read/write behavior, but it does not declare an explicit tool scope such as permissions or allowed-tools. That mismatch weakens least-privilege controls and can cause the host to grant broader filesystem access than reviewers or operators expect.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

L046-L061 明确规定缺少 sessions_spawn、sessions_send、sessions_history 时必须阻断执行,且“阻断状态下不允许创建或更新任务 registry”“禁止静默降级为 registry-only 模式”。但 L150-L170、L193-L204 仍将 list、switch、close、archive 定义为直接调用本地 task_registry.py 的操作,没有说明这些动作也必须受前述门禁约束,形成文档内部的意图冲突。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The task status response explicitly instructs the agent to reveal the bound sessionKey and full registry path. Those are sensitive internal identifiers and filesystem details that can aid session targeting, cross-task confusion, privacy leakage, or host reconnaissance, especially in a chat-facing skill intended for end users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The protocol defines commands, prompts, and fixed response templates entirely in Chinese and presents them as required behavior, but does not indicate that users can choose another language or opt in to this locale. Under the language/locale policy, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The diagnostic 任务状态 template explicitly exposes taskSessionKey and the registry storage path tasks/weixin/<account>/<peer>.json, even though the protocol earlier says sessionKey and routing internals should not be proactively exposed. These identifiers reveal internal session topology and account/peer-scoped storage structure, which can aid prompt-injection targeting, cross-task confusion attacks, privacy leakage, or operational reconnaissance by users who should only see task-level abstractions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
72% confidence
Finding

The document primarily defines command and response behavior in Chinese and presents English commands only as a later equivalence section, without stating that users can choose their preferred language. This can amount to an implicit language policy that forces a locale by default.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The troubleshooting output explicitly includes internal registry paths such as tasks/weixin//.json, and elsewhere the document permits exposing taskSessionKey in diagnostic views. Revealing internal storage layout and session identifiers can leak sensitive metadata, aid enumeration, and increase the blast radius of any downstream logging, support, or prompt-injection issue.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger phrase "继续" is a common conversational command and the test matrix expects it to route messages into the current task context. In a chat environment, such a broad trigger can cause accidental task routing or unintended state transitions when a user simply means "go on" in normal conversation, leading to context confusion and possible disclosure into the wrong task thread.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The restoration logic enumerates sibling account directories and imports task data from other account-scoped registry files when the local registry is empty or less populated. This creates unintended cross-account data access and persistence, which can expose task titles, summaries, tags, and session routing metadata outside the expected single-account or single-conversation boundary described by the skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code not only scans peer account directories for registry files but also synchronizes alias copies after writes, effectively propagating task state beyond the current account context. For a workbench intended to manage tasks within a single WeChat/OpenClaw conversation window, this broader file-system replication is unnecessary and increases the chance of unauthorized data mixing or leakage across accounts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The cross-account restoration path reads task data from peer account directories without any visible disclosure, confirmation, or audit signal in the normal output beyond an internal restoration field. This undermines user expectations about task isolation and can silently pull in data from unrelated accounts or identities.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Saving the registry automatically triggers alias synchronization with file copies, but there is no user-visible notice or consent for this extra propagation. Silent duplication of task data can surprise users and expand the exposure surface of potentially sensitive work summaries and session identifiers.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

L105 说明“除非用户明确要求查看实现细节,否则不要暴露 sessionKey”。但 L206-L214 中的“任务状态”流程在用户仅请求状态时就要求返回当前任务绑定的 sessionKey,这与前述隐藏实现细节的要求直接冲突。

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The task-creation command accepts broad natural-language forms like "新建任务" and "新建任务:..." without any stated exclusion rules. In mixed chat usage, this can cause unintended task creation from casual text or quoted content, producing registry changes and session spawning the user did not intend.

Content

No source excerpt is available for this finding.