Back to skill

Security audit

Ai Cv Weekly

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but manipulated inputs could inject unsafe HTML into delivered reports or influence YAML files written by custom preset creation.

Review before installing. Use only with trusted LLM, SMTP, and webhook configuration; assume report inputs, user hints, and summaries may be sent externally. Avoid opening or forwarding generated HTML reports from untrusted source material until HTML escaping/sanitization is fixed, and avoid custom preset creation until preset names are strictly validated.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
brief/renderer/markdown_parser.py:151
Finding

Stored HTML Injection in Generated Reports

Content
View full analysis
") h3_text = stripped[4:] num_html = "" m_num = _NUM_HEADING.match(h3_text) if m_num: num_html = f'
{int(m_num.group(1)):02d}
' h3_text = m_num.group(2) html.append(f'
{num_html}

{h3_text}

') in_item_block = True i += 1 continue if stripped.startswith("#### "): html.append(f"

{stripped[5:]}

") i += 1 continue kv_match = _KV_PATTERN.match(clean) if kv_match: label = kv_match.group(1) value = kv_match.group(2).strip() if "🦞" not in label: html.append( f'
{_inline(label)}' f'{_inline(value)}
' ) i += 1 continue if stripped.startswith("- ") and not stripped.startswith("---"): list_items = [stripped[2:]] i += 1 while i < len(lines) and lines[i].strip().startswith("- "): list_items.append(lines[i].strip()[2:]) i += 1 html.append("
    " + "".join(f"
  • {_inline(li)}
  • " for li in list_items) + "
") continue display = clean if clean != stripped else stripped if display: html.append(f"

{_inline(display)}

") def _inline(text: str) -> str: """Inline formatting: bold / italic / link.""" text = re.sub(r"\*\*(.+?)\*\*", r"\1", text) text = re.sub(r"\*(.+?)\*", r"\1", text) text = re.sub(r"\[(.+?)\]\((.+?)\)", r'\1< ...[truncated 2887 chars]
Remediation
View remediation

other

Warning
Location
brief/editors/stock.py:39
Finding

Indirect Prompt Injection Through Externally Fetched Content

Content
View full analysis
str: lines = [] for i, item in enumerate(items, 1): sub = item.source raw = item.raw_text[:500] pts = item.meta.get("points", "") pts_str = f" | 热度 {pts}" if pts else "" lines.append( f"{i}. **{item.title}**{pts_str}\n" f" 来源:{sub} | {item.url}\n" f" {raw}\n" ) return "\n".join(lines) ``` ```python def _build_user_prompt( self, items: list[Item], issue_number: int, user_hint: str ) -> str: today = datetime.now().strftime("%Y-%m-%d") prompt = f"请生成第 {issue_number} 期 {self.preset.display_name}。\n\n" prompt += f"**日期**: {today}\n**素材数**: {len(items)} 条\n" if user_hint: prompt += f"**用户提示**: {user_hint}\n" prompt += f"\n**今日 A 股相关资讯**:\n\n{_build_item_block(items)}\n" word_lo, word_hi = self.preset.target_word_count prompt += ( f"\n【要求】5 章节完整,{word_lo}-{word_hi} 字," "所有条目用 ### N. 格式并带 Claw 锐评。\n\n请生成 A 股日报:" ) return prompt ``` ```python # brief/editors/base.py system_prompt = self._build_system_prompt() user_prompt = self._build_user_prompt(items, issue_number, user_hint) for attempt in range(3): try: response = self.llm.chat( messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ], temperature=0.7, max_tokens=8000, ) ``` ### Technical Analysis Externally controlled source fields—including titles, descriptions, summaries, and URLs—are concatenated directly into the same user-message channel used for report-generation instructions. The application does not clea ...[truncated 1802 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
brief/custom_preset.py:84
Finding

Path Traversal in LLM-Generated Custom Preset Filename

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned and Unverified Third-Party Dependencies

Content
View full analysis
=3.9 requests>=2.31 jinja2>=3.1 pyyaml>=6.0 weasyprint>=60.0 # optional, used for HTML to PDF ``` ```bash # Install dependencies pip install -r requirements.txt ``` ### Technical Analysis Every dependency uses only a lower version bound. There is no lock file, upper bound, artifact hash, or documented package-index restriction. Consequently, two installations performed at different times can resolve materially different dependency and transitive-dependency versions. The package names are recognizable and the reviewed files do not specify suspicious package indexes or remote archives. The weakness is therefore not evidence that the currently named packages are malicious. It is a failure to preserve the dependency set that was reviewed and tested. Because Python packages and their build backends can execute code during installation, later compromise of an allowed package release or an unexpected dependency-resolution change can affect the host at installation time. ### Attack Path 1. A future package version satisfying one of the `>=` constraints is published or compromised. 2. A user follows the documented `pip install -r requirements.txt` command. 3. Pip resolves the newer package or a changed transitive dependency. 4. Package build or installation code executes with the user's installation privileges. 5. The altered package code subsequently runs inside the Skill process. ### Impact Assessment Impact depends on the privileges used to install and execute the Skill. A compromised dependency can potentially: - Execute code during installation. - Read files and environment variables accessible to the installer. - Alter report processing or network communications. - Access LLM, GitHub, or e ...[truncated 201 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (72)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · brief/editors/daily.py (reported line 91)May include surrounding context.

python
4. 简洁有力,不要凑字数

请生成日报:"""
        return prompt

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · brief/editors/finance.py (reported line 126)May include surrounding context.

python
4. 简洁有力,不要凑字数

请生成日报:"""
        return prompt

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · brief/editors/finance.py (reported line 183)May include surrounding context.

python
4. 简洁有力,不要凑字数

请生成日报:"""
        return prompt

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · brief/editors/stock.py (reported line 112)May include surrounding context.

python
4. 简洁有力,不要凑字数

请生成日报:"""
        return prompt

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · brief/editors/stock.py (reported line 176)May include surrounding context.

python
4. 简洁有力,不要凑字数

请生成日报:"""
        return prompt

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · brief/editors/stock.py (reported line 241)May include surrounding context.

python
4. 简洁有力,不要凑字数

请生成日报:"""
        return prompt

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · brief/editors/weekly.py (reported line 150)May include surrounding context.

python
4. 简洁有力,不要凑字数

请生成日报:"""
        return prompt

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The quick-start instructions ask users to configure an LLM API key, and later examples include webhook URLs, but the documentation does not warn that credentials must be protected or that prompts/report content may be sent to third-party services. For a skill handling fetched content and generated reports, this is a user-relevant privacy and security disclosure omission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The markdown states that generated reports can be delivered via Email and Webhook and pushed automatically by a Scheduler, which implies transmitting report contents to external systems. In this README section, there is no explicit warning about privacy, recipient correctness, or that report data will leave the local system.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrases are generic enough to overlap with ordinary user requests such as asking for a daily or weekly report, which can cause the skill to activate unintentionally. In a skill that can send email, post webhooks, and invoke external data sources, accidental activation increases the risk of unintended outbound actions and unnecessary data processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill advertises email and webhook delivery but does not clearly warn that generated content may be transmitted to external destinations. Because the skill also aggregates data, supports custom hints, and can run on schedules, users may unintentionally send sensitive prompts, summaries, or derived content outside the local environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The function sends a user's free-form description directly to an LLM, but this file provides no user-facing disclosure, consent, or warning that their text will be transmitted to an external model service. This can expose sensitive business, financial, or personal information if users include it in the preset request, and the finance-oriented context increases the chance that confidential investment or strategy details may be shared.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The generate() method sends system_prompt and user_prompt to self.llm.chat(...), which can transmit report inputs, item data, and user_hint to an external service. The file includes developer-oriented docstrings about LLM invocation, but no user disclosure, confirmation, or clear warning that potentially sensitive content is being sent out for processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code sends system_prompt and user_prompt to an external LLM via self.llm.stream(...), which is a network-style data transmission of report content and optional user hints. While the file documents that it performs LLM invocation, it does not provide a user-facing disclosure, confirmation, or warning that content will be transmitted off-process/off-system before streaming begins.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The schema rules are written as mandatory Chinese instructions, and the system prompt continues in Chinese with strict formatting requirements. This imposes a specific language/locale on generated output without offering the user any language choice or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The shared schema literal is written as a strict Chinese-only instruction block ("必须严格遵守") and is injected into both editor system prompts. Because no alternative locale or user preference mechanism is provided, this creates a hard language constraint across the skill's outputs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language instruction mandates Chinese output by framing the editor role and all schema/output requirements in Chinese, while also requiring Chinese explanations for first-use English terms. This imposes a specific language/locale on users without any opt-in or documented justification, which matches the language-policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The schema and all prompt templates are written to require Chinese-language section titles and output formatting, and the editors instruct the model in Chinese for A-share, HK, and US market briefs. This imposes a specific language choice across all outputs, including the US market editor, without offering the user any language or locale selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The prompt explicitly requires that, except for proper nouns, all content be translated into Chinese. This imposes a fixed language policy on generated output and does not offer the user any language or locale choice, which matches the policy-violation criterion for forced language selection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code sends the full messages payload to self.base_url via HTTP, which may include user or system data. Although the module docstring describes provider selection, it does not clearly warn users that prompt content will be transmitted to either OpenClaw or a third-party LLM service.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · brief/llm.py (reported line 71)May include surrounding context.

python
}

        try:
            resp = requests.post(url, headers=headers, json=payload, timeout=self.timeout)
            if resp.status_code == 200:
                data = resp.json()
                return data["choices"][0]["message"]["content"]

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stream() method posts the messages payload to a remote /chat/completions endpoint with streaming enabled. The file lacks a clear warning that user inputs are transmitted over the network to the selected provider, which is relevant for privacy and safety expectations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · brief/llm.py (reported line 113)May include surrounding context.

python
}

        try:
            resp = requests.post(
                url, headers=headers, json=payload,
                timeout=self.timeout, stream=True,
            )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The pipeline appends a Chinese-language instruction to the user hint during reruns, which imposes a specific language/locale behavior in generated content or prompting. This is a natural-language policy concern because the file does not offer the user a language choice or explain that Chinese-only prompt text will be used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

On quality retry, the code appends a Chinese instruction asking for complete sections, again enforcing a specific language in prompt construction. Because no user opt-in or locale configuration is visible here, this violates the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.