Back to skill

Security audit

Article Workflow

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its article-to-Feishu workflow purpose, but it needs review because credential backups and external storage behavior are not safely or clearly handled.

Review before installing. Use a least-privilege Feishu/Bitable token, keep the skill in a private directory, add ignore rules for .env, .env.*, .config.backup.json, config.backup.json, and config.local.json, and avoid analyzing private/internal URLs unless your fetch tool blocks local and private network destinations. Confirm whether Heartbeat automation is enabled before connecting it to group chats.

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

Warning
Location
SKILL.md:100
Finding
Unrestricted User-Controlled URL Fetching Enables SSRF<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:100-106`; related implementation flow in `core/analyzer.py:82-92, 118-134` **Vulnerability Type**: Server-Side Request Forgery through unrestricted URL fetching **Risk Level**: Medium ### Vulnerable Code `SKILL.md:100-106`: ```text Input: Article URL ↓ Main Agent smart routing (single-article mode) ├─ web_fetch retrieves content ├─ Analyze content + quality scoring ├─ Generate detailed report ├─ feishu_create_doc creates a document └─ feishu_bitable archives it to Bitable ``` `core/analyzer.py:82-92`: ```python # 2. Fetch content if it was not provided if title is None or content is None: fetched = self._fetch_content(url) if title is None: title = fetched.get("title", "") if content is None: content = fetched.get("content", "") ``` `core/analyzer.py:118-134`: ```python def _fetch_content(self, url: str) -> dict: """ Fetch article content Args: url: Article URL Returns: dict: {"title": str, "content": str} """ # This calls OpenClaw's web_fetch or browser tool. # The actual implementation requires integration with the OpenClaw tool system. return { "title": "", "content": "" } ``` ### Technical Analysis The Skill instructs the hosting Agent to pass an article URL to `web_fetch` or a browser tool. The URL originates from the user, but the reviewed workflow does not require validation of: - The URL scheme. - The destination hostname. - The resolved IP address. - Redirect destinations. - Loopback, link-local, private, reserved, or multicast address ranges. - Response size and request duration. Although retrieving remote articles is necessary for the declared functionality, unrestricted destination access exceeds the minimum network privilege needed to fetch public articles. The Python method is currently a placeholder rather than a direct network implementation. However, the opera ...[truncated 1795 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Implement a centralized URL-validation layer before every `web_fetch` or browser invocation: 1. Accept only `https` and, where explicitly required, `http`. 2. Reject URLs containing embedded credentials or malformed authority components. 3. Resolve the destination hostname and reject every address in loopback, private, link-local, multicast, unspecified, reserved, and documentation-only ranges. 4. Apply the same validation after every DNS resolution and to every redirect destination. 5. Consider an allowlist of supported public article domains. 6. Disable non-HTTP protocols, including `file`, `ftp`, `gopher`, and custom schemes. 7. Configure strict connection, read, and total timeouts. 8. Enforce response-size and content-type limits. 9. Run fetching through an isolated egress proxy that cannot access internal networks or cloud metadata. 10. Do not automatically archive fetched data until the destination and response have passed validation. 11. Add tests for IPv4, IPv6, alternative IP representations, DNS rebinding, and redirect-based bypasses. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
install.sh:18
Finding
Credential Backup and Environment Files Are Not Consistently Excluded from Version Control<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:18-39`; backup creation in `scripts/config_manager.py:20-22, 49-55`; related environment backup in `scripts/restore-config.sh:7-10` **Vulnerability Type**: Plaintext secret storage and incomplete version-control exclusions **Risk Level**: Medium ### Vulnerable Code `install.sh:18-39` creates the following `.gitignore`: ```bash cat > "$SKILL_DIR/.gitignore" << 'EOF' # Runtime data data/ logs/ # Configuration file containing sensitive information config.json # Python __pycache__/ *.py[cod] *$py.class *.so # macOS .DS_Store # Temporary files *.tmp *.bak EOF ``` `scripts/config_manager.py:20-22` defines sensitive local files: ```python CONFIG_FILE = SKILL_DIR / "config.json" CONFIG_BACKUP = SKILL_DIR / ".config.backup.json" ENV_FILE = SKILL_DIR / ".env" ``` `scripts/config_manager.py:49-55` creates a plaintext backup: ```python def backup_config(): """Back up the existing configuration.""" if CONFIG_FILE.exists(): import shutil shutil.copy2(CONFIG_FILE, CONFIG_BACKUP) print_success(f"Configuration backed up: {CONFIG_BACKUP}") return True ``` `scripts/restore-config.sh:7-10` also expects environment backups: ```bash CONFIG_FILE="$SKILL_DIR/../config.json" CONFIG_BACKUP="$SKILL_DIR/../.config.backup.json" ENV_FILE="$SKILL_DIR/../.env" ENV_BACKUP="$SKILL_DIR/../.env.backup" ``` ### Technical Analysis The configuration can contain the Bitable application token and table identifier. The backup logic copies that configuration into `.config.backup.json` without encryption. Other documented workflows use `.env`, `.env.backup`, `config.local.json`, and `config.backup.json`. The installer-generated `.gitignore` excludes `config.json` and files ending in `.bak`, but it does not exclude: - `.config.backup.json` - `.env` - `.env.backup` - `config.local.json` - `config.backup.json` The `*.bak` rule does not match `.env.backup` or files ending in `.json`. ...[truncated 1768 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Extend the generated `.gitignore` with explicit secret-file exclusions: ```gitignore config.json config.local.json config.backup.json .config.backup.json .env .env.* !.env.example .env.backup ``` 2. Store backups outside the repository and Skill publication directory. 3. Apply owner-only permissions, such as mode `0600`, to every configuration and backup file. 4. Prefer a platform secret manager or protected environment variables over plaintext files. 5. Add a pre-commit and pre-publication secret scanner. 6. Make installation fail safely if credential-bearing files are tracked by Git. 7. Replace token-shaped documentation examples with unmistakable placeholders. 8. Audit Git history for previously committed credentials. 9. If any credential was published, revoke and rotate it immediately rather than relying only on file deletion. 10. Restrict Feishu credentials to the minimum tables and operations required by this Skill. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (84)

Missing User Warnings

High
Confidence
98% confidence
Finding
The uninstall section documents irreversible `rm -rf` commands that delete the skill directory and associated data/log paths without a prominent warning about permanent data loss. Even though these are examples in documentation, users may copy-paste them directly, leading to accidental destruction of local files.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
# 1. 从 openclaw.json 移除配置(如果有)
# 2. 删除 Skill 目录
rm -rf ~/.openclaw/workspace/skills/article-workflow

# 3. 清理运行时数据(可选)
rm -rf ~/.openclaw/workspace/data/article-workflow
Confidence
96% confidence
Finding
Although narrowly scoped, the documentation includes a direct `rm -rf ~/.openclaw/workspace/skills/article-workflow` command that can be copy-pasted and will permanently remove the installed skill. In documentation for operational tooling, destructive shell commands are risky because users may execute them without verifying path expansion or confirming they are deleting the intended directory.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
# 1. 从 openclaw.json 移除配置(如果有)
# 2. 删除 Skill 目录
rm -rf ~/.openclaw/workspace/skills/article-workflow

# 3. 清理运行时数据(可选)
rm -rf ~/.openclaw/workspace/data/article-workflow
Confidence
96% confidence
Finding
Although narrowly scoped, the documentation includes a direct `rm -rf ~/.openclaw/workspace/skills/article-workflow` command that can be copy-pasted and will permanently remove the installed skill. In documentation for operational tooling, destructive shell commands are risky because users may execute them without verifying path expansion or confirming they are deleting the intended directory.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
rm -rf ~/.openclaw/workspace/skills/article-workflow

# 3. 清理运行时数据(可选)
rm -rf ~/.openclaw/workspace/data/article-workflow
rm -rf ~/.openclaw/workspace/logs/article-workflow
```
Confidence
95% confidence
Finding
The documented `rm -rf ~/.openclaw/workspace/data/article-workflow` permanently deletes runtime data and may remove user-important state such as cached records or statistics. In context, this is more dangerous because the same guide encourages hands-on shell usage and users may not distinguish optional cleanup from required uninstall steps.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
rm -rf ~/.openclaw/workspace/skills/article-workflow

# 3. 清理运行时数据(可选)
rm -rf ~/.openclaw/workspace/data/article-workflow
rm -rf ~/.openclaw/workspace/logs/article-workflow
```
Confidence
95% confidence
Finding
The documented `rm -rf ~/.openclaw/workspace/data/article-workflow` permanently deletes runtime data and may remove user-important state such as cached records or statistics. In context, this is more dangerous because the same guide encourages hands-on shell usage and users may not distinguish optional cleanup from required uninstall steps.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 3. 清理运行时数据(可选)
rm -rf ~/.openclaw/workspace/data/article-workflow
rm -rf ~/.openclaw/workspace/logs/article-workflow
```

---
Confidence
95% confidence
Finding
The log cleanup command irreversibly removes operational logs that may be needed for troubleshooting, auditing, or incident review. While the path is narrow and likely intentional, documenting forceful recursive deletion without warning creates avoidable risk of accidental loss.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 3. 清理运行时数据(可选)
rm -rf ~/.openclaw/workspace/data/article-workflow
rm -rf ~/.openclaw/workspace/logs/article-workflow
```

---
Confidence
95% confidence
Finding
The log cleanup command irreversibly removes operational logs that may be needed for troubleshooting, auditing, or incident review. While the path is narrow and likely intentional, documenting forceful recursive deletion without warning creates avoidable risk of accidental loss.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# 复制环境变量模板
cp .env.example .env

# 编辑 .env 文件,填入实际值
vi .env
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```
   # .gitignore
   config.json  # 包含敏感信息,不应提交
   .env         # 环境变量,不应提交
   ```

2. **修改工具覆盖配置**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```
   # .gitignore
   config.json  # 包含敏感信息,不应提交
   .env         # 环境变量,不应提交
   ```

2. **修改工具覆盖配置**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```
   # .gitignore
   config.json  # 包含敏感信息,不应提交
   .env         # 环境变量,不应提交
   ```

2. **修改工具覆盖配置**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```
   # .gitignore
   config.json  # 包含敏感信息,不应提交
   .env         # 环境变量,不应提交
   ```

2. **修改工具覆盖配置**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```
   # .gitignore
   config.json  # 包含敏感信息,不应提交
   .env         # 环境变量,不应提交
   ```

2. **修改工具覆盖配置**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SKILL_DIR/../config.json"
CONFIG_BACKUP="$SKILL_DIR/../.config.backup.json"
ENV_FILE="$SKILL_DIR/../.env"
ENV_BACKUP="$SKILL_DIR/../.env.backup"

echo "🔄 Article Workflow 配置恢复脚本"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SKILL_DIR/../config.json"
CONFIG_BACKUP="$SKILL_DIR/../.config.backup.json"
ENV_FILE="$SKILL_DIR/../.env"
ENV_BACKUP="$SKILL_DIR/../.env.backup"

echo "🔄 Article Workflow 配置恢复脚本"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SKILL_DIR/../config.json"
CONFIG_BACKUP="$SKILL_DIR/../.config.backup.json"
ENV_FILE="$SKILL_DIR/../.env"
ENV_BACKUP="$SKILL_DIR/../.env.backup"

echo "🔄 Article Workflow 配置恢复脚本"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The docstring and module description present this method as a real article-analysis workflow, but key steps are marked TODO or replaced with pass/commented code at L156-L178. Despite that, the function returns success=True with fabricated summary, tags, doc URL, and record ID at L180-L190, contradicting the documented behavior.

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
The README presents the skill primarily as an article-analysis workflow, but the documented execution flow includes side effects such as creating Feishu documents and archiving records into Bitable. This mismatch can lead users to submit article URLs or content without realizing their data will be persisted to external systems, increasing the risk of unintended disclosure or policy violations.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README states that the workflow automatically creates Feishu documents and archives data into Bitable, but it does not warn users that analyzed content, URLs, summaries, or metadata may be transmitted to and stored in external services. In a skill that processes arbitrary articles, this is dangerous because private, internal, or sensitive source material could be retained outside the immediate analysis context without informed consent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill description says results are archived to Feishu Bitable and documents, but it does not give an explicit user-facing warning that supplied article URLs, fetched content, summaries, and analysis results are sent to external Feishu services. This creates a data transparency and privacy risk, especially when users may provide internal, private, or sensitive links assuming processing is local.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The skill advertises Heartbeat-based automatic triggering but does not define clear scope boundaries, approved sources, rate limits, or confirmation requirements. That ambiguity can cause unintended processing of links from group chats or scheduled runs, leading to surprise external transmission of article URLs and generated content to Feishu services and unnecessary automated actions.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code's user-facing natural language is consistently fixed to Chinese, including the module description and workflow expectations, with no indication that users can opt into another language. The policy specifically flags language or locale constraints when they are imposed without user choice or clear justification.

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
The module documentation says that when run independently it supports both analysis and deduplication. In code, analyze() only checks for duplicates, while the cache update happens only in process() via add_url_to_cache at L336-L342, so standalone analysis does not actually persist dedup state.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The report template returned to users is entirely hardcoded in Chinese, so every generated document uses that language regardless of user preference. This is a natural-language policy issue unless the skill explicitly offers language selection or documents a justified regional constraint.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
This code file contains natural-language documentation entirely in Chinese and also hard-codes Chinese user-facing values such as field names and status labels. Under the policy, forcing a specific language without user opt-in or a documented regional justification is a language/locale policy violation.

Static analysis

Detected: suspicious.destructive_delete_command

Documentation contains a destructive delete command without an explicit confirmation gate.

Warn
Code
suspicious.destructive_delete_command
Location
docs/MIGRATION.md:199