Back to skill

Security audit

blog-polish-en-astro-cn

Security checks for vulnerabilities and agentic risk

Overview

This skill is mainly for blog polishing and translation, but its output directory handling can execute user-supplied shell commands and its file outputs are not fully aligned with its description.

Review before installing. Use only with trusted inputs, especially `outputDir`; a malicious or accidental value could execute shell commands. Confirm where generated English, Chinese, Astro, and image-directory outputs will be written, and avoid using this skill on sensitive drafts unless you are comfortable with derived copies being persisted.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:38
Finding

Arbitrary Shell Command Injection Through User-Controlled outputDir

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 38
Vulnerability Type: Shell command injection through unsafe eval
Risk Level: High

Vulnerable Code

sh
outputDir=$(eval echo "$outputDir")

Technical Analysis

The outputDir value originates from the Skill's input schema and is therefore user-controlled. Although it is enclosed in double quotes when passed to eval, eval reparses the resulting text as shell syntax. Command substitutions, shell operators, and other metacharacters contained in the input can consequently be executed rather than treated as path characters.

Using eval is unnecessary for resolving a leading ~ in a path. This creates an arbitrary command-execution primitive within a workflow that should only read a Markdown draft and write generated articles.

For example, a malicious value containing command substitution can trigger execution during initialization:

text
$(touch /tmp/skill-pwned)

Attack Path

  1. An attacker supplies a crafted outputDir through the Skill's input interface.
  2. The init workflow assigns that untrusted value to the shell variable.
  3. Line 38 passes the value through eval.
  4. The shell reparses command substitutions or metacharacters in the value.
  5. The injected command executes with the privileges and environment of the Agent or Skill runner.
  6. The attacker can invoke locally available commands and access resources available to that process.

This path does not require a network request or a malicious packaged script; exploitation occurs through the normal outputDir parameter.

Impact Assessment

Successful exploitation permits arbitrary local command execution under the Skill process account. Depending on that account's permissions, an attacker may be able to:

  • Read files accessible to the Agent runner.
  • Create, modify, overwrite, or delete accessible files.
  • Execute installed programs and scripts.
  • Access environment variables and other proce ...[truncated 340 chars]
Remediation
View remediation

Remediation Suggestions

Remove eval entirely. If expansion of a literal home-directory prefix is required, handle only explicitly supported forms with shell parameter operations:

sh
case "$outputDir" in
  "~")
    outputDir="$HOME"
    ;;
  "~/"*)
    outputDir="$HOME/${outputDir#~/}"
    ;;
esac

Apply the following additional hardening measures:

  1. Validate that outputDir is a non-empty path without control characters.
  2. Resolve it to a canonical path using a safe platform-appropriate mechanism.
  3. Enforce an allowlisted parent directory, such as the designated OpenClaw workspace.
  4. Reject paths that escape the allowed root through .. components or symbolic links.
  5. Keep variables quoted in all filesystem operations.
  6. Create the destination with restrictive permissions before writing.
  7. Add regression tests using values containing $(...), backticks, semicolons, newlines, spaces, glob characters, and traversal sequences to verify that no shell evaluation occurs.
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (18)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation states that the polished markdown is saved, but the executable workflow never writes generated content to disk and only returns an output path. In agent pipelines, this can mislead downstream components into trusting a file artifact that does not exist, causing integrity issues, stale-file reuse, or accidental processing of an older file at the same path.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says the skill should polish and translate the draft, then convert the English edition into Astro-compatible markdown. However, the add-astro-frontmatter step builds the Astro file by embedding $(cat "$draftPath"), which copies the original input draft rather than the polished English output. This is a semantic mismatch in the core advertised behavior, not a minor implementation detail.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description requires the draft to be translated into English and Simplified Chinese (zh-CN) as a fixed behavior, which imposes specific language and locale outputs. The file does not indicate that users can choose a different language or opt into the locale constraint, so this is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation in When to Use explicitly says this skill is for blog polishing/translation to zh-CN 'without images'. In contrast, the Astro conversion step injects image: ./hero.png and creates an images/ directory, which is an active contradiction of the documented no-images intent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest outputSchema declares a single required field outputPath and the prose documentation repeats Return: { outputPath: "/full/path/to/file.md" }. However, the finalize step actually emits { engOutputPath, chnOutputPath, astroPath }, which directly contradicts the stated output behavior rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The listed triggers include generic phrases like "polish my draft" and "translate blog to Chinese," which are broad enough to match common user speech outside a narrowly scoped invocation context. The description also does not provide exclusion conditions or tighter constraints to distinguish when this specific skill should activate versus other writing or translation skills.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill writes multiple output files to disk but the markdown description does not clearly warn users about those side effects. In an agent setting, unclear write behavior can lead to unintended modification of the workspace, confusion about where data was stored, and accidental persistence of sensitive draft content in additional derived files.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file description limits the skill to polishing and translating into Simplified Chinese only. However, the provided skill-manifest context for this skill states it should also produce an English edition and convert that English output into Astro-compatible markdown, which this file's declared behavior and workflow do not cover.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The description requires the article to be translated into Simplified Chinese (zh-CN) as a fixed behavior, and the document does not mention any user language selection or opt-in mechanism. This can violate language/locale policy when a skill forces a specific locale without offering a choice or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The listed trigger "polish my draft" is a generic phrase that could match many ordinary writing-assistance requests outside the intended technical-blog zh-CN translation context. Although the sentence mentions technical blog drafts, it does not provide exclusion examples or tighter trigger constraints, increasing the risk of unintended invocation.

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 159)May include surrounding context.

md
## Workflow Summary

1. **Resolve paths** + create timestamp (`date +"%y%m%d%H%M"`)
2. **Read draft** from `draftPath`
3. **Polish English**: Fix grammar/spelling, improve clarity, structure into 4-5 sections, target 1000-1200 words
4. **Translate to zh-CN**: Preserve code blocks, inline code, technical terms (`openclaw`, `skill`, `cli`)

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_chn.md (reported line 94)May include surrounding context.

md
## Workflow Summary

1. **Resolve paths** + create timestamp (`date +"%y%m%d%H%M"`)
2. **Read draft** from `draftPath`
3. **Polish English**: Fix grammar/spelling, improve clarity, structure into 4-5 sections, target 1000-1200 words
4. **Translate to zh-CN**: Preserve code blocks, inline code, technical terms (`openclaw`, `skill`, `cli`)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description mandates output in English and Simplified Chinese, and the rest of the file reinforces this fixed language behavior. This is a natural-language locale policy concern because the user is not offered a language choice or an explicit opt-in for the forced locales.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The step description and comments state that the code creates an Astro-compatible slug from the filename or title. But the final line save_state slug omits the computed value, so the generated slug is not actually persisted for later steps. This contradicts the documented intent of the step because the code does not fully implement the described behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documented workflow and output section describe saving a polished markdown file and returning its path. In addition to that, the code creates a separate Astro markdown file and an images subdirectory, expanding the behavior beyond the stated save operation. These extra filesystem outputs are not reflected in the manifest description or workflow summary.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The heading and usage instructions frame the skill as operating specifically in en-US and zh-CN without presenting alternatives or user choice. This constitutes a locale policy issue under the rule because the language constraint is imposed rather than opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The listed triggers include broad phrases like "polish my draft" that could match many ordinary editing requests outside this skill's intended scope. The file does not provide exclusion conditions or tighter constraints beyond a brief mention of technical blog drafts, increasing the chance of unintended invocation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The workflow and defaults describe where outputs are saved, but they do not clearly warn the user that the skill will create files and a directory structure under the configured output path. For a skill that modifies the filesystem, a brief user-facing warning would improve safety disclosure.

Content

No source excerpt is available for this finding.