Back to skill

Security audit

Wb Buddy Checkin Publish

Security checks for vulnerabilities and agentic risk

Overview

This skill performs the advertised WorkBuddy daily check-in, but it also uses local login tokens, authenticated API calls, scheduled-task persistence, and unverified PowerShell delegation in ways users should review carefully.

Install only if you are comfortable with a skill reading local WorkBuddy/CodeBuddy login state, making authenticated requests to copilot.tencent.com, moving and clicking your Windows cursor, saving local screenshots/state files, and creating a temporary Windows scheduled task during update recovery. Prefer a version that separates API token use from GUI automation, asks before scheduled-task creation or app restart, and does not auto-run unverified PowerShell from another skill.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (3)

T06 · System Persistence

Error
Location
scripts/wb_mouse_checkin.py:769
Finding
Automatic Registration of a Cross-Session Windows Scheduled Task<![CDATA[ ## Vulnerability Details **File Location**: `scripts/wb_mouse_checkin.py:769-795` **Vulnerability Type**: Operating-system scheduled-task persistence **Risk Level**: High ### Code Evidence ```python def schedule_resume_task(): """Register a Windows scheduled task that runs this script in resume mode.""" try: py = sys.executable script = os.path.abspath(__file__) st = time.strftime("%H:%M", time.localtime(time.time() + RESUME_DELAY_SEC)) r = subprocess.run( ["schtasks", "/create", "/tn", RESUME_TASK_NAME, "/tr", f'"{py}" "{script}" -resume', "/sc", "once", "/st", st, "/f"], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30) if r.returncode == 0: print(f"Scheduled resume task [{RESUME_TASK_NAME}] for {st}") return True print(f"Failed to register scheduled task: {r.stderr.strip() or r.stdout.strip()}") return False except Exception as e: print(f"Scheduled-task registration error: {e}") return False def cancel_resume_task(): """Delete the resume scheduled task when it is no longer required.""" try: subprocess.run(["schtasks", "/delete", "/tn", RESUME_TASK_NAME, "/f"], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30) print(f"Deleted scheduled task [{RESUME_TASK_NAME}]") except Exception: pass ``` The task is activated from the update-recovery path at `scripts/wb_mouse_checkin.py:948-960`: ```python if btn: sx, sy, size = btn announce_move((sx, sy), "restart and upgrade") click_at(sx, sy, "restart and upgrade") mark_pending("update_restart") # Register an independent Windows task before WorkBuddy restarts. schedule_resume_task() ``` The same behavior is explicitly described in `SKILL.md:119-121`. ### Technical Analysis The GUI ch ...[truncated 2890 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic scheduled-task creation from the normal `-run` workflow. 2. Report update/restart status to the user and require an explicit retry after WorkBuddy returns. 3. If resume scheduling is essential, expose it as a separate opt-in command and obtain informed confirmation before creating the task. 4. Generate a unique per-installation task name and reject existing-name collisions instead of using `/f`. 5. Configure an explicit expiration and deletion policy for the task. 6. Delete the task on every terminal path, including timeout, exception, failed check-in, and missing-window paths. 7. Check and report the actual return code from `schtasks /delete`. 8. Store the scheduled executable in a protected, immutable installation directory and verify its integrity before resumed execution. 9. Prefer `wb_api_checkin.py`, which performs the declared check-in without desktop persistence. ]]>

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/wb_mouse_checkin.py:412
Finding
Execution of an Unverified External PowerShell Script with Execution Policy Bypass<![CDATA[ ## Vulnerability Details **File Location**: `scripts/wb_mouse_checkin.py:412-466` **Vulnerability Type**: Untrusted local tool execution and tool hijacking **Risk Level**: High ### Code Evidence ```python def _find_desktop_control_ps1(): cand = os.path.join(os.path.expanduser("~"), ".workbuddy", "skills", "desktop-control-win", "scripts", "screen-info.ps1") return cand if os.path.exists(cand) else None def take_screenshot(hwnd, out_path): """Capture the window client area, preferring desktop-control.""" ps = _find_desktop_control_ps1() if ps: try: env = dict(os.environ) env.pop("ACC_PRODUCT_CONFIG_V3", None) r = subprocess.run( ["powershell.exe", "-ExecutionPolicy", "Bypass", "-File", ps, "-Action", "screenshot", "-Target", TARGET_TITLE, "-OutputPath", out_path], capture_output=True, text=True, encoding="utf-8", errors="replace", env=env, timeout=60) if r.returncode == 0 and os.path.exists(out_path): return True except Exception: pass return _screenshot_pw(hwnd, out_path) ``` ### Technical Analysis The screenshot function searches a predictable path under the current user's home directory for another Skill's `screen-info.ps1`. Existence is the only trust check. If the file exists, it is executed by PowerShell with `-ExecutionPolicy Bypass`. The implementation does not verify: - A cryptographic hash or digital signature. - File ownership or access-control settings. - That the resolved file remains inside an approved installation directory. - The identity or version of the external Skill. - Whether the file changed after installation. - Whether the PowerShell executable itself resolves to an expected trusted binary. The `subprocess.run` invocation uses an argument list and does not enable a command shell, so the shown argument ...[truncated 1815 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic external PowerShell delegation and always use the bundled `_screenshot_pw()` implementation. 2. If integration with `desktop-control-win` is required, make it an explicit user-controlled option rather than automatic discovery. 3. Pin and validate a cryptographic hash or trusted publisher signature before execution. 4. Resolve the candidate path canonically and verify that it remains within an approved, protected installation root. 5. Validate file ownership and ACLs, rejecting files writable by untrusted principals. 6. Avoid `-ExecutionPolicy Bypass`; use signed scripts and the normal PowerShell policy. 7. Resolve PowerShell through a trusted system path and validate the executable identity if PowerShell remains necessary. 8. Fail safely when verification fails instead of executing the external file. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wb_mouse_checkin.py:491
Finding
Color-Only UI Detection Can Trigger Unintended Clicks and Application Restart<![CDATA[ ## Vulnerability Details **File Location**: `scripts/wb_mouse_checkin.py:491-566` **Vulnerability Type**: Unsafe heuristic UI automation **Risk Level**: Medium ### Code Evidence ```python def detect_update_overlay(path): """Detect a WorkBuddy update banner and return its presumed button position.""" try: w, h, ch, buf = load_png(path) except Exception: return None if w < 200 or h < 200: return None y0 = int(h * 0.85) cands = [] for y in range(y0, h, 2): for x in range(0, w, 2): i = (y * w + x) * ch r, g, b = buf[i], buf[i+1], buf[i+2] if g >= 150 and g - r >= 40 and b >= 90 and r <= 180: cands.append((x, y)) if len(cands) < 100: return None bucket = {} for x, y in cands: key = (x // 60, y // 60) bucket.setdefault(key, []).append((x, y)) best_key = max(bucket, key=lambda k: len(bucket[k])) pts = bucket[best_key] if len(pts) < 80: return None ix = int(sum(p[0] for p in pts) / len(pts)) iy = int(sum(p[1] for p in pts) / len(pts)) sx, sy = img_to_screen(ix, iy, w, h) return (sx, sy, len(pts)) ``` The returned coordinate is clicked without validating the UI control's text or identity: ```python def handle_update_overlay(pre_path, timeout=180): btn = detect_update_overlay(pre_path) if not btn: return 'not_found' sx, sy, size = btn announce_move((sx, sy), "update button") click_at(sx, sy, "update button") ``` Window selection also contains a substring fallback at `scripts/wb_mouse_checkin.py:527-548`: ```python if title == TARGET_TITLE: found_exact[0] = hwnd return False if TARGET_TITLE in title and found_substr[0] is None: found_substr[0] = hwnd ... return found_exact[0] or found_substr[0] or user32.FindWindowW(None, TARGET_TITLE) ``` ### Technical Analysis The script infers that an update-and-restart button exists solely ...[truncated 2718 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic application update and restart from the check-in workflow. 2. If an update banner blocks check-in, stop and request explicit user confirmation. 3. Verify the owning process executable, expected installation path, publisher signature, and process ID before interacting with a window. 4. Remove substring window-title fallback or constrain it using validated process identity. 5. Use Microsoft UI Automation or accessibility APIs to locate a control by exact accessible name, role, and bounding rectangle. 6. Require multiple independent signals, such as exact dialog structure and semantic control identity; do not rely on color clustering alone. 7. Revalidate the target window and control immediately before generating the click. 8. Abort when the user remains active after the idle timeout instead of continuing to seize the cursor. 9. Provide a mode that only reports the blocking update banner and never interacts with it. ]]>
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims to be a pure ctypes/Windows-API automation, but it also documents persistence and execution behaviors such as scheduled task creation, local state storage, and external PowerShell/subprocess use. These extra behaviors expand the blast radius from simple UI automation to durable system modification and process orchestration, which users may not anticipate.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill claims to be a pure ctypes/Windows-API automation, but it also documents persistence and execution behaviors such as scheduled task creation, local state storage, and external PowerShell/subprocess use. These extra behaviors expand the blast radius from simple UI automation to durable system modification and process orchestration, which users may not anticipate.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
This section documents an API-based mode that contradicts the stated GUI-only skill purpose by harvesting local login state and using it to perform authenticated remote actions. Such scope drift is dangerous because it bypasses the user's mental model and introduces credential handling and network-side effects not disclosed at the top level.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
Reading local authentication files and replaying bearer tokens to backend endpoints is a sensitive capability that goes beyond normal desktop clicking. If misused, it can enable unauthorized account actions, token exposure, or expansion to other backend operations using the same login state.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The script materially differs from the declared skill behavior: instead of GUI automation and screenshot-based verification, it performs direct authenticated API actions using a locally recovered bearer token. That expands the skill's capability from visible user-interface automation to hidden account-level operations, undermining user consent and enabling silent actions against a remote service.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The code reads bearer tokens from local auth files in the user's profile, including a fallback token source that is broader than the stated check-in purpose. Accessing unrelated local authentication material is dangerous because those tokens can authorize remote actions as the user and create a reusable credential-handling primitive beyond simple desktop clicking.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
ps = _find_desktop_control_ps1()
    if ps:
        try:
            env = dict(os.environ)
            env.pop("ACC_PRODUCT_CONFIG_V3", None)  # 防超大环境块撑爆 PowerShell Add-Type
            r = subprocess.run(
                ["powershell.exe", "-ExecutionPolicy", "Bypass", "-File", ps,
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
This block implements creation and use of Windows Task Scheduler entries to relaunch the script later, which is a classic persistence capability. In the context of a simple GUI automation skill, this is disproportionate and dangerous because it enables execution outside the current session flow and can continue operating after the parent application exits or restarts.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The scheduled-task guidance tells users to run an automation that foregrounds the WorkBuddy window and performs mouse/click actions, but it does not explicitly warn that the automation can seize the cursor and interfere with active user input. In this skill's context, that omission matters because the README itself describes cursor movement, foreground-window manipulation, and timed execution, which can cause unintended clicks or disrupt the user's work if run while the machine is in use.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares no explicit tool scope, yet the documentation describes capabilities spanning local file access, shell/task scheduling, environment-dependent token discovery, and authenticated network requests. Without a constrained manifest, an agent may invoke this skill with broader privileges than users expect, increasing the chance of unauthorized filesystem, process, or network actions.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The '何时使用' section lists activation examples like '自动签到' and 'Buddy 加油站签到', but especially '自动签到' is broad and could match unrelated daily check-in or sign-in tasks. The file does not provide exclusion conditions or clearer scope boundaries to ensure the skill is invoked only for WorkBuddy daily points collection.

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
The privacy comment is misleading: although the token is not written to disk, it is used to authenticate outbound requests to a remote Tencent endpoint. Misrepresenting credential handling is dangerous because it obscures the true data flow and can cause users or reviewers to underestimate that the script transmits authenticated requests on their behalf.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
            env = dict(os.environ)
            env.pop("ACC_PRODUCT_CONFIG_V3", None)  # 防超大环境块撑爆 PowerShell Add-Type
            r = subprocess.run(
                ["powershell.exe", "-ExecutionPolicy", "Bypass", "-File", ps,
                 "-Action", "screenshot", "-Target", TARGET_TITLE, "-OutputPath", out_path],
                capture_output=True, text=True, encoding="utf-8", errors="replace",
Confidence
89% confidence
Finding
The script invokes PowerShell with -ExecutionPolicy Bypass to run another skill's script discovered from the user's skill directory. This trusts external local code without integrity verification, so a tampered or replaced desktop-control-win script would execute in the user's context and could capture screens or run arbitrary commands.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The skill's stated purpose is daily WorkBuddy check-in, but this code also detects update overlays and clicks update/restart controls. Triggering an application restart changes system and application state beyond the declared task, can interrupt the user, and creates an unexpected control path that may be abused or cause denial of service-like disruption.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
py = sys.executable
        script = os.path.abspath(__file__)
        st = time.strftime("%H:%M", time.localtime(time.time() + RESUME_DELAY_SEC))
        r = subprocess.run(
            ["schtasks", "/create", "/tn", RESUME_TASK_NAME,
             "/tr", f'"{py}" "{script}" -resume',
             "/sc", "once", "/st", st, "/f"],
Confidence
95% confidence
Finding
The script creates a Windows scheduled task that will later launch Python with this script in -resume mode. Even though the command is built from local values rather than direct user input, creating OS-level scheduled tasks is a persistence mechanism that exceeds the stated daily click/check-in purpose and can survive process restarts, increasing risk if the script or its directory is later modified.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script registers and deletes scheduled tasks without a prominent upfront warning or consent flow. Because scheduled tasks are an OS-level execution and persistence mechanism, silently introducing them materially changes the user's security posture and is more dangerous than ordinary local temp-file creation.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def cancel_resume_task():
    """删除续签计划任务(续签完成/不需要时清理, 防止残留)。"""
    try:
        subprocess.run(["schtasks", "/delete", "/tn", RESUME_TASK_NAME, "/f"],
                       capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30)
        print(f"== 已删除续签计划任务 [{RESUME_TASK_NAME}]")
    except Exception:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
During normal operation the script captures screenshots of the WorkBuddy window and saves them to disk. Even if limited to a target application, screenshots can contain names, messages, account details, or internal business information, and storing them by default increases local privacy and data-retention risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
Running with -run immediately performs foreground takeover, cursor movement, and real clicks with no final confirmation checkpoint. Because this manipulates the active desktop and intentionally waits for the user's mouse to become idle before taking control, it can interfere with user activity and cause unintended actions if the window focus or UI state is different than expected.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The README's natural-language instructions are exclusively in Chinese, which effectively forces a specific language for users without any opt-in or alternative locale. Under the stated policy, language-specific constraints should either offer user choice or be clearly documented as a justified locale-specific limitation.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The manifest description is entirely written in Chinese and the skill instructions assume Chinese UI terms and phrasing, but there is no statement that the skill is region-specific or that users may choose another language. Under the policy, forcing a specific language without opt-in can be a natural-language policy violation unless the locale restriction is clearly documented and justified.

Missing User Warnings

Low
Confidence
80% confidence
Finding
This markdown file describes a calibration flow where the script saves measured coordinates to `calibrate.json` and later reuses them. Because markdown files should warn about behaviors affecting user data or system state, the file write should be disclosed more explicitly as a persisted configuration change.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The HTTP request hard-codes `Accept-Language: zh`, which imposes a specific language/locale choice regardless of user preference. This is a natural-language policy concern because the file does not offer any locale selection or explain a justified region-specific requirement.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The script writes and removes `checkin_state.json` as part of its resume workflow, which is a file-write/delete operation. While the code logs these actions when they occur, the main runtime entry path does not clearly warn the user up front that executing the skill will create and later delete state files in the local directory.

Static analysis

No suspicious patterns detected.