Back to skill

Security audit

Dinstein Tech News Digest

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its tech-news digest purpose, but its broad URL fetching and some under-disclosed credential/file behavior create review-worthy security risk.

Review before installing in environments with access to private networks or cloud metadata services. Use only trusted source configs, disable enrichment if you do not need full-text fetching, avoid giving broad GitHub credentials, and confirm scheduled Discord/email targets before enabling recurring delivery.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T01 · Skill Instruction Hijacking

Note
Location
references/digest-prompt.md:120
Finding

Mandatory Branding and External Link Injection into Generated Reports

Content
View full analysis
| | Powered by OpenClaw ``` ``` ### Technical Analysis The Skill instructions require the Agent to append fixed project branding and an external repository link to generated reports. The footer is not derived from the user's requested news content and is propagated into archived reports and configured delivery channels. Because this behavior is mandatory rather than optional, loading and following the Skill changes the Agent's final output by inserting third-party promotional content. This is classified as instruction hijacking under the supplied audit taxonomy, although it does not grant code-execution or system privileges. ### Attack Path 1. A user invokes the Skill to create a technology-news digest. 2. The Agent reads `references/digest-prompt.md`. 3. The Agent follows the mandatory “Stats Footer” instruction. 4. The project branding and external URL are inserted into the report. 5. The modified report is archived and may be redistributed through Discord or email. ### Impact Assessment The issue affects the integrity and neutrality of generated content. It can cause users to unknowingly redistribute unsolicited branding and an external link across all configured output channels. No filesystem, credential, code-execution, or elevated system privileges are obtained through this behavior. The scope is limited to generated report content and its subsequent distribution. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch-rss.py:125
Finding

Server-Side Request Forgery Through Unrestricted RSS Feed URLs

Content
View full analysis
str: """Resolve relative links against the feed URL. Rejects non-HTTP(S) schemes.""" if not link: return link if link.startswith(("http://", "https://")): return link resolved = urljoin(base_url, link) if not resolved.startswith(("http://", "https://")): return "" # reject javascript:, data:, etc. return resolved ``` Configured feed URLs are requested without destination validation: ```python req = Request(url, headers=req_headers) try: with urlopen(req, timeout=TIMEOUT) as resp: ``` The schema accepts any URI and does not restrict the destination to public HTTP or HTTPS hosts: ```json "url": { "type": "string", "format": "uri", "description": "RSS feed URL (required for type=rss)" } ``` ### Technical Analysis Workspace configuration overrides can define arbitrary RSS feed URLs. The implementation permits HTTP and HTTPS destinations but does not reject: - IPv4 or IPv6 loopback addresses. - RFC 1918 private networks. - Link-local addresses. - Cloud instance metadata services. - Multicast, reserved, or otherwise non-public ranges. - Hostnames resolving to private addresses. - Redirects from public hosts to internal destinations. - DNS-rebinding scenarios where resolution changes between validation and connection. Checking only the scheme does not establish that a destination is safe. `urllib.request.urlopen()` follows HTTP redirects by default, so an initially public URL can redirect to an internal endpoint. ### Attack Path 1. An attacker gains the ability to provide or modify the workspace source configuration. 2. The attacker adds an enab ...[truncated 1351 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/enrich-articles.py:49
Finding

Server-Side Request Forgery Through Article Full-Text Enrichment

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/summarize-merged.py:45
Finding

Indirect Prompt Injection Through Untrusted News Content

Content
View full analysis
/references/templates/
Remediation
View remediation
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (58)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code chunk does not implement the declared primary functionality of collecting and processing tech news from multiple external sources. Instead, it is a standalone formatting/export utility whose purpose is to convert an existing markdown report into a styled PDF. PDF output is also not mentioned in the declared description, which instead cites Discord, email, and markdown templates. While this script could be a supporting component within a larger digest pipeline, its actual behavior is materially different from the declared purpose and omits nearly all of the headline capabilities described.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description describes a comprehensive tech news aggregation and digest-generation system with multi-source ingestion, scoring, retries, deduplication, and multiple output channels. The supplied code chunk does not implement any of those core behaviors. Instead, it is a narrowly scoped utility that sanitizes an existing markdown report into safe HTML for email output. While HTML email output could be a supporting component of the larger declared system, this specific code chunk’s actual purpose is materially different from the declared end-to-end functionality and omits the key advertised capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code does not implement the declared primary functionality of collecting tech news from RSS, Twitter/X, GitHub, Reddit, or web search, nor does it perform quality scoring, deduplication, or digest generation. Instead, it performs a narrower but distinct capability: constructing and sending HTML emails with optional PDF attachments using local mail tools. While email output is mentioned in the description, this chunk is specifically a message transport utility, and its primary behavior is outbound email transmission from local files. That is a materially different purpose from the declared digest-generation pipeline, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

  • WEB_SEARCH_BACKEND - Web search backend: auto|brave|tavily (optional, default: auto)
    • BRAVE_API_KEYS - Brave Search API keys, comma-separated for rotation (optional)
    • BRAVE_API_KEY - Single Brave key fallback (optional)
    • GITHUB_TOKEN - GitHub personal access token (optional, improves rate limits)
  1. Generate Digest:
    bash

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/fetch-github.py (reported line 428)May include surrounding context.

python
- `WEB_SEARCH_BACKEND` - Web search backend: auto|brave|tavily (optional, default: auto)
   - `BRAVE_API_KEYS` - Brave Search API keys, comma-separated for rotation (optional)
   - `BRAVE_API_KEY` - Single Brave key fallback (optional)
   - `GITHUB_TOKEN` - GitHub personal access token (optional, improves rate limits)

3. **Generate Digest**:
   ```bash

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

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

  • Anti-pattern: Do NOT copy pipeline steps into the cron prompt — it will drift out of sync

Multi-Channel Delivery Limitation

OpenClaw enforces cross-provider isolation: a single session can only send messages to one provider (e.g., Discord OR Telegram, not both). If you need to deliver digests to multiple platforms, create separate cron jobs for each provider:

text
# Job 1: Discord + Email

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file states 'All prompts, templates, comments, and code in English' while separately noting output language is runtime-controlled. This imposes an organizational language constraint in the skill materials without presenting a user choice or documented justification, which matches the locale/language policy violation criteria.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description limits supported output formats/channels to Discord, email, and markdown templates. The README explicitly claims a use case that delivers news to Telegram, which expands the advertised behavior beyond the declared skill scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

该Markdown文件明确描述了技能会自动安装、配置、定时并将科技日报发送到频道,属于可能影响隐私或外部发布的行为。按规则,Markdown应对可能影响用户数据、隐私或系统完整性的行为提供警示,但这里仅强调“全程对话完成”和自动推送,没有任何提醒。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

文档直接要求设置Twitter/X、Tavily、Brave、GitHub等API密钥,这些都属于隐私和账户安全相关的敏感凭据。按照Markdown文件的规则,应对可能影响用户数据或隐私的行为给出警告,但此处没有任何关于密钥泄露、最小权限或用途的说明。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares capabilities to read environment variables, read and write files, access the network, and execute shell-driven workflows, but it does not define an explicit permission or allowed-tools scope. That increases the attack surface because operators and downstream agents cannot easily constrain what the skill is permitted to do, especially given its cron/prompt-driven execution model.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The daily cron prompt template sets LANGUAGE = English as a fixed instruction. This is a natural-language locale policy concern because the skill prescribes a specific language by default and does not indicate user opt-in or an alternative selection mechanism in that prompt.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The weekly cron prompt repeats a fixed LANGUAGE = English setting. Because the policy applies to natural-language instructions in all file types, this is a locale restriction unless the skill clearly offers a language choice or justifies why English is required.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

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

  • Anti-pattern: Do NOT copy pipeline steps into the cron prompt — it will drift out of sync

Multi-Channel Delivery Limitation

OpenClaw enforces cross-provider isolation: a single session can only send messages to one provider (e.g., Discord OR Telegram, not both). If you need to deliver digests to multiple platforms, create separate cron jobs for each provider:

text
# Job 1: Discord + Email

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The security notes state that no files outside the workspace are accessed, but the same document allows reading a GitHub App private key from an arbitrary filesystem path and using the gh credential store. This kind of misleading security claim can cause unsafe deployment decisions, because operators may trust the skill with broader host access than intended.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes a skill for generating tech news digests from six declared source types, but this configuration adds many RSS, Twitter/X, GitHub, and Reddit sources explicitly tagged for "crypto". Crypto-specific monitoring is a distinct editorial scope from general tech-news digestion, so the configured behavior is broader than the manifest claims.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This JSON manifest contains multiple Chinese-language sources and Chinese note text, such as 36氪, 机器之心 Synced, 量子位 QbitAI, and InfoQ 中文, but the file provides no indication that users can choose or opt into Chinese-language content. Under the stated policy, forcing or silently including a specific language/locale without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This JSON config includes Chinese search terms such as "大模型最新动态" and "大模型" as built-in defaults for the LLM topic. Because the file provides no user opt-in, locale selection, or justification for mixing languages, it imposes a language/locale behavior that may conflict with organizational language-choice policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The AI Agent topic includes the Chinese term "AI 智能体" in default Twitter queries, and later topics also include Chinese-language queries. This is a natural-language locale choice embedded in defaults, but the config does not indicate that users can choose or disable that locale behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The placeholder table sets <LANGUAGE> to Chinese as the default, which establishes a specific language choice by default rather than offering a user-selected locale. This is reinforced later by the instruction to write the report in <LANGUAGE>, with no opt-in or alternative locale selection described.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The directive Write the report in <LANGUAGE> inherits a default of Chinese from the template and does not provide a user-facing choice or opt-in mechanism. That creates a natural-language locale policy issue because the skill effectively forces a language setting unless the caller manually edits the template.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The template explicitly instructs the agent to send generated content to a Discord channel or DM using configured identifiers, but it provides no warning, confirmation step, or visibility check before delivery. In a skill that aggregates external content from multiple sources, this increases the risk of unintentionally posting sensitive, inappropriate, or user-unreviewed content into a public or wrong-recipient destination.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file describes the PDF output as using Chinese typography, and later examples and font requirements reinforce a Chinese-language presentation by default. Because the template specifies a particular language/locale style without any opt-in or alternative, it creates a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script reads a GitHub App private key, writes it to a temporary file on disk, and then invokes openssl to sign with it. Even though the temp file is deleted afterward, writing key material to disk increases exposure through local file disclosure, backup/forensic recovery, race conditions, or reuse on multi-user systems, especially since the path is in a globally writable /tmp-backed environment on many platforms.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/fetch-github.py (reported line 65)May include surrounding context.

python
f.write(private_key)
        tmp_key = f.name
    try:
        result = _sp.run(
            ['openssl', 'dgst', '-sha256', '-sign', tmp_key],
            input=signing_input.encode(), stdout=_sp.PIPE, stderr=_sp.PIPE, universal_newlines=False, timeout=10,
        )

Static analysis

No suspicious patterns detected.