Back to skill

Security audit

Content Parser

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent URL-extraction purpose, but its shell-based curl examples and broad arbitrary-URL handling create a real review concern before installation.

Review this skill before installing. Use it only for public URLs you intend to send to the Marswave/ListenHub API, avoid private or signed links, and be aware that extracted content and raw API responses may be saved locally. The shell command examples should be treated carefully because unsafe substitution of a crafted URL could execute unintended local commands.

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:195
Finding
Command Injection Through Unsafe URL Interpolation in a Shell Command<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 195-205 **Vulnerability Type**: Shell command injection caused by unsafe construction of a JSON request body **Risk Level**: High ### Vulnerable Code ```bash curl -sS -X POST "https://api.marswave.ai/openapi/v1/content/extract" \ -H "Authorization: Bearer $LISTENHUB_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "source": { "type": "url", "uri": "https://en.wikipedia.org/wiki/Topology" } }' ``` The workflow instructs the Agent to replace the example URI with the user-supplied URL: ```json { "source": { "type": "url", "uri": "{url}" } } ``` ### Technical Analysis The Skill accepts an arbitrary user-provided HTTP(S) URL and directs the Agent to construct a `curl` command whose JSON body is enclosed in a single-quoted shell string. The only documented validation is that the value must be an HTTP(S) URL. An otherwise valid URL can contain an apostrophe and shell metacharacters. If the Agent performs direct textual substitution of `{url}` into the demonstrated command, an apostrophe in the URL terminates the shell's single-quoted JSON argument. Subsequent characters can then be interpreted as shell syntax rather than request data. JSON quoting does not provide shell quoting, and checking only the URL scheme does not prevent this condition. This is an exploitable coding pattern because the Skill explicitly requires shell-based `curl` requests while providing no safe serialization or argument-passing mechanism for the untrusted value. ### Attack Path 1. An attacker supplies a crafted URL that begins with an accepted `http://` or `https://` scheme but contains an apostrophe followed by shell syntax. 2. The Agent accepts the URL because the documented validation only requires an HTTP(S) URL. 3. The user confirms extraction as required by the workflow. 4. The Agent substitutes the attacker-controlled URL into the single-quoted JSON body shown b ...[truncated 1086 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never interpolate a user-controlled URL directly into a shell command or quoted JSON literal. 2. Serialize the request body with a JSON-aware tool such as `jq`: ```bash REQUEST_BODY=$(jq -n --arg uri "$USER_URL" '{ source: { type: "url", uri: $uri } }') curl -sS -X POST "https://api.marswave.ai/openapi/v1/content/extract" \ -H "Authorization: Bearer $LISTENHUB_API_KEY" \ -H "Content-Type: application/json" \ --data-binary "$REQUEST_BODY" ``` 3. Prefer invoking an HTTP client through a structured tool API that accepts the URL, headers, and JSON body as separate arguments, avoiding shell interpretation entirely. 4. Parse the supplied URL using a proper URL parser. Permit only `http` and `https`, reject embedded credentials in the authority component, and reject malformed control characters. 5. Do not rely on allowlisting characters alone as the primary defense. Safe argument separation and JSON serialization must remain mandatory. 6. Add tests covering apostrophes, quotes, command substitutions, semicolons, newlines, control characters, and URLs with encoded special characters. 7. Avoid printing or persisting authorization headers, and warn users before submitting signed URLs or URLs containing sensitive query parameters to the third-party extraction service. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (10)

Vague Triggers

Medium
Confidence
96% confidence
Finding
The manifest declares triggers including "extract content" and a broad condition like "another skill needs to parse source material," which are not tightly scoped to this specific URL-extraction skill. These phrases could match many ordinary requests and increase the chance of unintended invocation.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
Several required user-facing prompts are specified only in Chinese, such as the config summary and setup questions. This imposes a language choice on users without offering a locale preference or documenting a justified region-specific constraint.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
   TASK_ID="<id-from-step-3>"
   for i in $(seq 1 60); do
     RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/content/extract/$TASK_ID" \
       -H "Authorization: Bearer $LISTENHUB_API_KEY" 2>/dev/null)
     STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.status // "processing"')
     case "$STATUS" in
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
   TASK_ID="<id-from-step-3>"
   for i in $(seq 1 60); do
     RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/content/extract/$TASK_ID" \
       -H "Authorization: Bearer $LISTENHUB_API_KEY" 2>/dev/null)
     STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.status // "processing"')
     case "$STATUS" in
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
   TASK_ID="<id-from-step-3>"
   for i in $(seq 1 60); do
     RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/content/extract/$TASK_ID" \
       -H "Authorization: Bearer $LISTENHUB_API_KEY" 2>/dev/null)
     STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.status // "processing"')
     case "$STATUS" in
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
   TASK_ID="<id-from-step-3>"
   for i in $(seq 1 60); do
     RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/content/extract/$TASK_ID" \
       -H "Authorization: Bearer $LISTENHUB_API_KEY" 2>/dev/null)
     STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.status // "processing"')
     case "$STATUS" in
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The skill writes full extracted content and raw API responses to local files in the current directory, which can persist sensitive data from parsed URLs without strong user-specific consent at the point of write. Saving raw API responses is especially risky because metadata or unexpected fields may contain sensitive or unnecessary information beyond what the user expects from simple parsing.

External Transmission

Medium
Category
Data Exfiltration
Content
3. Submit extraction

```bash
curl -sS -X POST "https://api.marswave.ai/openapi/v1/content/extract" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The documented support for 'Any HTTP(S) URL' creates a very broad activation and processing scope, which can cause the skill to fetch and parse arbitrary attacker-controlled URLs. In a content-parsing skill, this increases the risk of misuse such as unintended external requests, parsing untrusted internal endpoints if downstream controls are weak, or activation in contexts broader than users expect.

Context-Inappropriate Capability

Low
Confidence
91% confidence
Finding
The manifest frames this skill as extracting and parsing content from URLs, but the instructions add persistent local config creation and saving behavior in `.listenhub/content-parser/config.json`. While result saving may be adjacent to extraction, maintaining local configuration state is not an obvious requirement of a URL parsing skill's stated purpose.

Static analysis

No suspicious patterns detected.