Back to skill

Security audit

Pacer Skill

Security checks for vulnerabilities and agentic risk

Overview

Pacer is a coherent career-planning skill, but it stores sensitive resume, financial, and progress details too broadly and renders user-derived data into executable chart HTML without clear safeguards.

Review this skill before installing. It is not clearly malicious, but only use it if you are comfortable with detailed career, resume, financial-runway, and weekly progress information being saved locally and reused. Avoid putting secrets or unnecessary personal details in uploaded CVs, and prefer a version that adds explicit memory opt-in, deletion controls, narrowed triggers, safer chart data encoding, and pinned installation instructions.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
charts/map-compare.html:275
Finding
Stored HTML and JavaScript Injection in Chart Templates<![CDATA[ ## Vulnerability Details **File Location**: `charts/map-compare.html:275-287`; related unsafe substitutions also occur in `charts/map-compare.html:106-114, 199-205`, `charts/map-radar.html:62-66`, and `charts/simulate-timeline.html:52-60` **Vulnerability Type**: Stored HTML/JavaScript injection **Risk Level**: High ### Vulnerable Code ```javascript // 渲染方向说明列表 const list = document.getElementById('directionList'); const directions = [ { name: dirAName, reason: "{{direction_a_reason}}", step: "{{direction_a_step}}" }, { name: dirBName, reason: "{{direction_b_reason}}", step: "{{direction_b_step}}" } ]; if (dirCName && dirCName !== "{{direction_c_name}}") { directions.push({ name: dirCName, reason: "{{direction_c_reason}}", step: "{{direction_c_step}}" }); } directions.forEach(d => { const item = document.createElement('div'); item.className = 'direction-item'; item.innerHTML = `<span class="direction-name">${d.name}</span>:${d.reason} · <span class="first-step">第一步:${d.step}</span>`; list.appendChild(item); }); ``` Additional substitutions are placed directly into executable JavaScript contexts: ```javascript const mode = "{{mode}}"; const ganttLabels = {{gantt_labels}}; const ganttStart = {{gantt_start}}; const ganttDuration = {{gantt_duration}}; const ganttTasks = {{gantt_tasks}}; ``` ```javascript const pathName = "{{path_name}}"; const dataPathA = {{data_path_a}}; const dataStatusQuo = {{data_status_quo}}; const milestoneIndex = {{milestone_index}}; const milestoneLabel = "{{milestone_label}}"; const turningPointIndex = {{turning_point_index}}; const hoverLabelsPathA = {{hover_labels_path_a}}; const hoverLabelsStatusQuo = {{hover_labels_status_quo}}; ``` ### Technical Analysis The chart workflow reads career information from user input and persistent memory, substitutes it into complete HTML documents, and renders those documents in an iframe. The templates do not define contextual escaping or strict schema validation. String ...[truncated 2222 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `innerHTML` and construct each element with `createElement` and `textContent`. 2. Serialize every value used in JavaScript with a trusted JSON serializer. Do not concatenate values into quoted JavaScript strings. 3. Validate substituted data against strict schemas: - Scores, percentages, dates, and indexes must have bounded numeric types. - Arrays must have fixed maximum lengths and typed elements. - Status values and modes must use explicit allowlists. - Text values must have reasonable length limits. 4. Prefer placing serialized data in an `application/json` element and parsing it rather than generating executable source code. 5. Render generated charts in a sandboxed iframe. Avoid `allow-same-origin`, top-level navigation, popups, and other privileges unless strictly required. 6. Apply a restrictive Content Security Policy that limits scripts to approved sources and restricts outbound connections. 7. Add tests using quotation marks, closing script tags, event-handler markup, template literals, and malformed JSON to verify that all values remain inert text. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
prompts/system.md:10
Finding
Excessive Persistent Storage of Sensitive Career and Financial Data<![CDATA[ ## Vulnerability Details **File Location**: `prompts/system.md:10-12, 37-42`; `prompts/scan.md:25-46, 61`; `prompts/scan-cv-parser.md:41-54`; `prompts/track.md:128-150` **Vulnerability Type**: Excessive sensitive-data retention without lifecycle controls **Risk Level**: Medium ### Vulnerable Instructions ```markdown ## 核心原则 - **陪伴,不说教**:你的角色是帮用户找到"适合自己的答案",而不是给出"正确答案" - **直接,不废话**:每句话都有用,不说客套话,不绕弯子 - **每次只问一个问题**:永远只聚焦最关键的那一个问题,等用户回答后再问下一个 - **记住一切**:用户说过的每一件事都存入 memory,对话时自然引用,不让用户重复解释 ``` ```markdown ## 记忆管理 所有用户数据存储在 OpenClaw 本地 memory,格式为 Markdown: - 路径:`~/.openclaw/memory/pacer-[用户ID]-track.md` - 每次对话开始时读取 memory,自然引用已知信息 - 每次有新信息时及时更新 memory ``` The Scan workflow explicitly collects and retains financial and personal profile information: ```markdown 3. 💰 **经济状况** > "你现在有多少个月的生活储备?大概说个范围就行。" 4. 🤝 **人脉资源** > "你身边哪个行业认识的人最多?" 5. 🔥 **核心动力** > "你最不能忍受的工作状态是什么?" **收集信息过程中的规则:** - 用户给的信息越模糊,越要追问一次具体细节,但只追问一次 - 不评价用户的回答,只确认和记录 - 将所有回答存入 memory ``` The CV parser stores employment and education data: ```markdown ## CV 解析结果 - 最近职位:[职位名称] @ [公司类型] - 总工作年限:[X] 年 - 职能层级:[初级/中级/高级/管理层] - 所在行业:[行业名称] - 核心技能:[技能1, 技能2, 技能3, ...] - 教育背景:[学历] · [专业] · [学校] - 提取时间:[时间戳] ``` ### Technical Analysis The Skill instructs the agent to store every statement made by the user rather than limiting persistence to the minimum fields required for career tracking. Persisted information can include CV-derived employment and education history, financial reserves, professional contacts, motivations, milestones, weekly commitments, and daily activity records. The reviewed instructions do not provide: - An explicit opt-in step before persistent storage. - A retention or automatic expiration period. - A user-accessible deletion or export workflow. - A prohibition against retaining raw CV content or unrelated conversation. - File-permission or encryption requirements. - Documented isolation requirements for multiple users. Local storage reduces exposure com ...[truncated 1419 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the instruction to remember everything with explicit data minimization. 2. Obtain clear user consent before enabling persistent memory or storing CV-derived fields. 3. Separate transient conversation context from long-term tracking data. 4. Do not retain raw CV contents or unrelated statements after extracting the approved fields. 5. Provide commands to view, export, correct, and permanently delete all Pacer memory. 6. Define a retention period and automatically expire inactive profiles and detailed activity logs. 7. Enforce per-user isolation and restrictive filesystem permissions for memory files. 8. Encrypt sensitive records at rest where supported, especially on shared systems. 9. Document which fields are stored, why they are needed, and how long they remain. 10. Allow users to use the planning features without persistent memory when weekly tracking is not requested. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (34)

Vague Triggers

High
Confidence
96% confidence
Finding
The activation phrases are very broad and include common terms like "规划", "career", "下一步", and "我该怎么办", which could trigger the skill during ordinary conversation unrelated to intentional use. In a skill that handles sensitive career data and may initiate multi-step guidance or tracking, unintended invocation increases the chance of accidental data disclosure, confusing responses, and unconsented workflow activation.

Missing User Warnings

High
Confidence
96% confidence
Finding
The prompt explicitly instructs the agent to store parsed CV data in memory, including employment history, skills, education, inferred seniority, and industry. This is sensitive personal data, and the skill provides no notice, consent step, retention limit, or data-minimization control before persistence, creating a privacy and unauthorized-retention risk.

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill instructs the agent to automatically extract sensitive personal and CV-derived data and continue the workflow without any notice, consent, or disclosure about storage and use. Because CVs commonly contain employment history, education, contact details, and other sensitive information, silent ingestion and downstream memory use creates a meaningful privacy and data-governance risk.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README encourages users to upload CVs and describes automatic extraction plus ongoing weekly progress tracking, but it does not clearly disclose what personal data is stored, for how long, who can access it, or whether tracking persists across sessions. Because CVs commonly contain highly sensitive personal and employment information, missing privacy and retention disclosures can lead to uninformed consent and unsafe handling of personal data.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding
The installation instructions invoke `npx clawhub@latest install pacer`, which fetches and executes the latest package version at runtime rather than a pinned, reviewed version. This creates a supply-chain risk: if the package or one of its dependencies is compromised, users may execute attacker-controlled code during installation.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger phrases include very broad everyday terms such as 'career', '规划', '我该怎么办', and '不知道做什么', which can cause the skill to activate in many unrelated conversations. Over-broad activation increases the chance of unintended invocation, unnecessary access to user context or files, and confusion or interference with other skills.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This is a markdown file, so SQP-2 applies to missing warnings in the skill description. Line L12 states that AI reads user data from memory and injects it into HTML for rendering, but the document does not include any warning or disclosure about user-data use, privacy implications, or rendering risks.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The document sets `lang="zh"`, and all visible UI text and inline comments are written in Chinese, which indicates the skill is fixed to a specific language. The provided file does not offer a user language choice or document a region-specific reason for this restriction, which matches the locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The document declares `lang="zh"`, and all visible user-facing text is in Chinese, which imposes a specific language/locale without offering user opt-in or a documented reason. This matches the policy category for language or locale constraints that are not optional or justified.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The document sets `lang="zh"` at L002 and all visible UI text is in Chinese, which imposes a specific language/locale on users. Under the policy, locale restrictions should either be optional for the user or clearly justified as region-specific.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The example shows the skill ingesting an uploaded PDF resume and immediately extracting employment history and capabilities without any visible notice about how uploaded personal data is handled, retained, or shared. Resumes commonly contain sensitive personal and professional information, so silent processing increases privacy and consent risk, especially in a career-coaching context where users may assume broad confidentiality.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill asks for the user's financial runway in months, which is sensitive financial information, without warning the user that this data is sensitive or explaining why it is needed. In a career-transition scenario, this can pressure users into disclosing private financial details that could affect profiling, targeting, or misuse if stored or exposed.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This markdown file contains user-facing dialogue and instructions exclusively in Chinese, which can impose a language requirement on users without opt-in. The policy allows locale constraints only when the skill offers a choice or clearly documents a justified region-specific limitation, neither of which appears here.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The entire example dialogue and instructional framing are presented only in Chinese, with no indication that the user can choose another language or locale. Under the policy for natural-language violations, forcing a specific language without user opt-in is in scope.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This markdown skill file presents all user-facing dialogue and instructions exclusively in Chinese, which effectively forces a specific language for interaction. The policy allows language constraints only when the skill offers user opt-in or clearly documents a justified locale limitation, neither of which appears here.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This markdown file is natural-language content, so policy checks apply. The dialogue and instructions are fully Chinese-language and do not provide any user opt-in, alternative language option, or justification that the skill is intended only for a Chinese-speaking audience, which can violate language/locale policy requirements.

Vague Triggers

Medium
Confidence
95% confidence
Finding
Automatically entering this module immediately after a scan is an ambiguous activation condition because it does not require a fresh, explicit user request for planning. That can lead the agent to proceed into additional analysis and personalized recommendations beyond what the user clearly asked for, increasing the risk of unintended actions or privacy-invasive inference.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger phrase includes broad everyday language such as asking what options are available, which can accidentally activate the planning workflow during ordinary conversation. In an agent context, over-broad activation can cause unintended collection, inference, or generation based on personal career data without sufficiently clear user intent.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The listed triggers include broad conditions like first-time use, absence of a memory record, and the phrase '重新开始', which can arise in many ordinary interactions without clearly indicating intent to run this scan workflow. The file does not provide scope limits, exclusion conditions, or negative examples to distinguish when the skill should not activate.

Ssd 3

Medium
Confidence
99% confidence
Finding
The instruction to store all answers in memory without limitation or minimization encourages persistent retention of sensitive personal data, including finances, professional background, network information, and motivations. Unbounded retention increases the risk of privacy harm, over-collection, secondary misuse, and exposure in future unrelated interactions.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger conditions include broad, everyday phrases such as “模拟一下” and “X个月后会怎样”, which can cause the skill to activate outside the intended career-planning context. This is dangerous because accidental invocation can route unrelated conversations into this module, producing irrelevant outputs and reducing user control over agent behavior.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger list is broad enough to match common conversational phrases such as '下一步' or '我该怎么办', which can cause the skill to activate outside the user's explicit intent. In a career-oriented assistant, this creates a boundary/control issue: unrelated conversations may be redirected into the Pacer workflow and associated memory behaviors without a clear opt-in.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill instructs persistent storage of all user data to a local memory file and to read it at each conversation start, but there is no visible user-facing notice or consent mechanism in the skill description. This creates a privacy risk because sensitive career information may be retained and reused without the user's informed awareness, increasing the chance of over-collection and unintended disclosure on the local system.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrase "我完成了..." is broad enough to match ordinary conversation outside the intended tracking workflow, which can cause the skill to activate unexpectedly. In this skill, unintended activation is more dangerous because activation can lead to persistence of user progress data into local memory and generation of follow-up tracking behavior.

Static analysis

No suspicious patterns detected.