Back to skill

Security audit

Workbuddy Usage Status

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a disclosed WorkBuddy usage-dashboard tool with local report generation, local archiving, and an optional user-supplied WorkBuddy billing API check.

Install only if you want a local WorkBuddy usage report. Treat generated HTML, JSON, JS, CSV, and archive files as private because they can contain session titles, error snippets, and up to 300 characters of prompt text. Do not use --billing-token-file unless you intentionally want the skill to send your manually copied WorkBuddy session credential to workbuddy.cn for billing data, and delete or invalidate that token file afterward.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Rogue AgentSelf-Modification, Session Persistence
Findings (18)

Ae1

High
Category
analysis-evasion
Content
python3 scripts/usage_extractor.py [--out <输出目录>] [--home <数据根>] [--credit-xlsx <路径>] [--billing-token-file <路径>] [--seed <旧快照>] [--no-archive]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- `chart.umd.min.js` —— 图表引擎,由抽取器从 skill 包复制到输出目录,需与 HTML 同目录存放。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- `chart.umd.min.js` —— 图表引擎,由抽取器从 skill 包复制到输出目录,需与 HTML 同目录存放。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Hidden Instructions

High
Category
Prompt Injection
Content
<meta charset="UTF-8" data-page-node-id="uh7S5G2MLok2kjQ6Q6RjI1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" data-page-node-id="ZG3EVOPAq7G5TW9HwmdUAo" />
<title>Workbuddy使用数据看板</title>
<!--CHART_JS_ASSET_TAG-->
<style>
  :root{
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Tainted flow: 'req' from open (line 308, file read) → urllib.request.urlopen (network output)

High
Category
Data Flow
Content
headers={"Content-Type": "application/json", header_key: header_val},
    )
    ctx = ssl.create_default_context()
    with urllib.request.urlopen(req, timeout=30, context=ctx) as resp:
        payload = json.loads(resp.read().decode("utf-8"))
    if payload.get("code") != 0:
        raise RuntimeError("用量 API 返回错误: %r" % (payload.get("msg"),))
Confidence
80% confidence
Finding
File contents flow to a network sink. This may indicate data exfiltration of sensitive files.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
L028 states the skill only reads ~/.workbuddy, implying a strictly local-only scope. However, later sections explicitly document an optional mode that sends an HTTPS request to WorkBuddy's billing API using user-supplied credentials, so the 'only reads ~/.workbuddy' statement is contradicted by the documented capability.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
At L061 the documentation says the skill accesses WorkBuddy data in a read-only, non-intrusive way. But elsewhere the same README documents writing a dashboard HTML, JSON/JS, CSV, copied Chart.js file, and automatic archive data under ~/.workbuddy/usage-archive/, which are persistent filesystem side effects rather than purely read-only behavior.

Session Persistence

Medium
Category
Rogue Agent
Content
permissions:

- file_read
- file_write
- network
  metadata:
  clawdbot:
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
permissions:

- file_read
- file_write
- network
  metadata:
  clawdbot:
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- `--no-archive`:禁用自动归档合并(默认开启,不建议)。
  
  > ⚠️ **用户侧 token 安全提醒**:该 token 文件等同于你的 WorkBuddy 会话凭证,**请当作密码保管**——① 不要提交到任何 Git 仓库 / 云盘 / 聊天工具;② 限制文件权限(如 `chmod 600`),用完即删或在 workbuddy.cn 退出登录使其失效;③ 不要分享给他人,也不要长期留存明文。skill 只在使用该参数时联网一次,且绝不自动读取宿主 App 的凭据存储。

执行后在该目录生成 5 个文件:
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Unbounded Output

Medium
Category
Output Handling
Content
* https://github.com/kurkle/color#readme
 * (c) 2023 Jukka Kurkela
 * Released under the MIT License
 */function _t(t){return t+.5|0}const yt=(t,e,i)=>Math.max(Math.min(t,i),e);function vt(t){return yt(_t(2.55*t),0,255)}function Mt(t){return yt(_t(255*t),0,255)}function wt(t){return yt(_t(t/2.55)/100,0,1)}function kt(t){return yt(_t(100*t),0,100)}const St={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},Pt=[..."0123456789ABCDEF"],Dt=t=>Pt[15&t],Ct=t=>Pt[(240&t)>>4]+Pt[15&t],Ot=t=>(240&t)>>4==(15&t);function At(t){var e=(t=>Ot(t.r)&&Ot(t.g)&&Ot(t.b)&&Ot(t.a))(t)?Dt:Ct;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Tt=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function Lt(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Et(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Rt(t,e,i){const s=Lt(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function It(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e<i?6:0):e===n?(i-t)/s+2:(t-e)/s+4}(e,i,s,h,n),r=60*r+.5),[0|r,l||0,a]}function zt(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(Mt)}function Ft(t,e,i){return zt(Lt,t,e,i)}function Vt(t){return(t%360+360)%360}function Bt(t){const e=Tt.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?vt(+e[5]):Mt(+e[5]));const n=Vt(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return zt(Rt,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return zt(Et,t,e,i)}(n,o,a):Ft(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const Wt={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg"
...[truncated 28 chars]
Confidence
75% confidence
Finding
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The script reads a user-supplied authentication token file and sends a credentialed request, but the implementation provides no strong runtime disclosure or confirmation at the point of use. In a skill context that otherwise emphasizes local read-only processing and zero external requests by default, this can surprise users into transmitting sensitive browser-derived credentials and expands the trust boundary to a remote service.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script extracts user_query content from local project JSONL files and writes it into usage-status.json, usage-status.js, the generated HTML, and CSV exports. Those prompts can contain secrets, proprietary code, personal data, or copied credentials, so exporting them into broadly readable artifacts materially increases exposure beyond the original local store.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
These lines describe a bilingual interface with a language toggle, but also say the default language is Chinese. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy issue unless the locale constraint is explicitly justified.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
Line L219 states that CSV headers and section names automatically follow the operating system language, producing Chinese on Chinese systems and English otherwise. This imposes a locale choice based on system settings rather than offering the user an explicit language selection or opt-in, which matches the language/locale policy violation category.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The HTML root sets `lang="zh-CN"`, which establishes Chinese as the default language for the skill UI. Although a manual language toggle exists later, the initial experience still forces a specific locale unless the user's browser locale happens to select English in script logic, which can conflict with a policy requiring user choice or opt-in.

Intent-Code Divergence

Low
Confidence
83% confidence
Finding
The comment on L1104 states this section includes '全量CSV' (full CSV), suggesting CSV export functionality is implemented below. However, the subsequent code only defines a CSV cell escaping helper and renders dashboard/session details; no actual CSV export action, file generation, or download flow appears in this file. This is an active documentation-to-code mismatch rather than a mere omission.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The module docstring, usage, and all user-facing output strings are written only in Chinese, which effectively constrains the skill to a specific language. The file does not offer user opt-in or an alternate locale, and no justification is given that the tool is intentionally region-specific beyond referencing a Chinese service.

Static analysis

No suspicious patterns detected.