Back to skill

Security audit

Content Summarizer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a URL/text summarizer scaffold, but it can fetch arbitrary locations and stores content in /tmp with weak boundaries, so users should review it carefully before installing.

Use this only with public, non-sensitive URLs or text. Do not provide localhost, internal, cloud metadata, file://, authenticated, or confidential sources. Set OUTPUT_DIR to a private directory and delete generated files when done, and treat generated AI prompts as containing untrusted source content before using them with any tool-enabled agent.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/url-to-summary.sh:5
Finding

Unrestricted URL Fetching Enables SSRF and Local File Disclosure

Content
View full analysis
" echo "Example: $0 https://example.com/article" exit 1 fi mkdir -p "$OUTPUT_DIR" TIMESTAMP=$(date +%s) TMP_CONTENT=$(mktemp) TMP_CLEAN=$(mktemp) TMP_SENTENCES=$(mktemp) trap "rm -f $TMP_CONTENT $TMP_CLEAN $TMP_SENTENCES" EXIT echo "Fetching: $URL" >&2 curl -sL --max-time 30 -A "Mozilla/5.0 (compatible; ContentSummarizer/1.0)" "$URL" > "$TMP_CONTENT" 2>/dev/null ``` `scripts/key-points.sh:19-21`: ```bash if [[ "$INPUT" =~ ^https?:// ]]; then CONTENT=$(curl -sL --max-time 30 -A "content-summarizer/1.0" "$INPUT" || true) ``` ### Technical Analysis Both network-fetching paths accept attacker-controlled destinations and invoke `curl` with redirect following enabled through `-L`. The implementation does not: - Restrict destinations to approved external hosts. - Reject loopback, link-local, private, multicast, or reserved IP ranges. - Resolve hostnames and validate all returned addresses. - Revalidate the destination after every redirect. - Limit `url-to-summary.sh` to HTTP or HTTPS URI schemes. In `url-to-summary.sh`, an arbitrary string is passed directly to `curl`. Consequently, any URI scheme supported by the installed curl build may be accepted. This can include `file://`, allowing files readable by the Skill process to be copied into the generated summary workflow. The minimum-length checks limit which files produce successful output but do not prevent the underlying read. Although `key-points.sh` initially requires an HTTP or HTTPS-looking input, `curl -L` can follow an attacker-controlled redirect to an int ...[truncated 1949 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/url-to-summary.sh:117
Finding

Untrusted Content Is Embedded Directly into Downstream LLM Prompts

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/url-to-summary.sh:6
Finding

Sensitive Summary Data Is Written to Predictable Files in a Shared Temporary Directory

Content
View full analysis
" echo "Example: $0 https://example.com/article" exit 1 fi mkdir -p "$OUTPUT_DIR" TIMESTAMP=$(date +%s) TMP_CONTENT=$(mktemp) TMP_CLEAN=$(mktemp) TMP_SENTENCES=$(mktemp) ``` `scripts/url-to-summary.sh:82-84`: ```bash OUTPUT_FILE="${OUTPUT_DIR}/summary-${TIMESTAMP}.md" cat > "$OUTPUT_FILE" << EOF ``` The heredoc subsequently includes the complete cleaned source text: ```bash Article text: $CLEAN_TEXT ``` `scripts/summarize.sh:5-6,27-32`: ```bash OUTPUT_DIR="${OUTPUT_DIR:-/tmp/summaries}" mkdir -p "$OUTPUT_DIR" TIMESTAMP=$(date +%s) OUTPUT_FILE="${OUTPUT_DIR}/summary-text-${TIMESTAMP}.md" WORD_COUNT=$(echo "$TEXT" | wc -w) READ_TIME=$((WORD_COUNT / 200)) # Extract key sentences ``` The file is then created through ordinary shell redirection: ```bash cat > "$OUTPUT_FILE" << EOF ``` ### Technical Analysis Both scripts store source content beneath the fixed shared path `/tmp/summaries` by default. They do not: - Set a restrictive `umask`. - Enforce mode `0700` on the output directory. - Enforce mode `0600` on output files. - Verify that the output directory is owned by the current user. - Create output files atomically with `mktemp`. - Prevent following a pre-existing symbolic link. - Avoid predictable filenames. The filename contains only a second-resolution timestamp. A local attacker can predict likely output names. Ordinary shell redirection follows symbolic links and truncates the link target using the victim process's permissions. The `mktemp` usage for intermediate files is appropria ...[truncated 1784 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a functioning content summarization pipeline with extraction, analysis, metadata generation, and AI-ready structured outputs based on fetched content. The code only fetches URL content or accepts text/stdin, checks that the content is at least 100 characters, and emits a generic template explicitly stating that actual AI-powered extraction is not implemented here. This is a material mismatch in primary purpose and implemented capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description presents this as a tool that can fetch arbitrary URLs and extract clean text from HTML for summarization. The supplied code does not perform any network access, URL retrieval, or HTML parsing/cleaning. Instead, it only summarizes already-provided text from stdin or arguments and emits a markdown template with extracted sentences and an AI prompt. While the summarization/template aspects partially match the description, the prominent declared capability of fetching URLs and processing HTML is absent, making the description materially inaccurate.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file name/comment and manifest describe content extraction and structured summarization behavior, but the implementation never parses HTML, identifies key sentences, generates metadata, or performs any extractive summarization. After optionally fetching a URL, the script only checks length and prints placeholder sections, so its actual behavior is much narrower than advertised.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises executable behavior via shell commands, file output to /tmp, and URL fetching, but does not declare any explicit tool scope such as allowed-tools or permissions. In an agent environment, missing tool scoping weakens least-privilege controls and can allow broader-than-expected file and shell access if the skill is invoked automatically.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

Overly broad activation language such as 'Fetch any URL' and 'Transform any URL or raw text' can cause an agent to invoke the skill in contexts not intended by the user, including fetching attacker-controlled or sensitive endpoints. In autonomous workflows, vague triggers increase the risk of SSRF-like access patterns, untrusted content ingestion, and accidental processing of local or internal resources.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documentation does not warn users that it retrieves external content and stores resulting summaries under /tmp/summaries, which can expose sensitive fetched data to local users, logs, or later processes. Lack of disclosure about network access and local persistence increases the chance of unintentional data handling violations and unsafe use with confidential URLs or text.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The markdown output example shows completed sections like a '2-3 paragraph summary,' a polished tweet hook, and concrete key takeaways as if the skill generates them directly. Elsewhere, the file states the skill extracts key sentences algorithmically and emits an 'AI enhancement prompt' to paste into another LLM, which contradicts the later output example and implies broader autonomous summarization than described.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comment on L02 states 'Extract key points from URL or text', which implies the script itself performs extraction. However, the output note on L53 admits it is only a template for use with another agent, directly contradicting the documented intent of this script.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest describes a skill that can fetch any URL, extract clean text from HTML, and then summarize it. This script instead accepts only direct text input via arguments or stdin and exits with a usage message if no text is supplied, showing a clear mismatch between the advertised capability and the implemented behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script stores the full supplied text, including potentially sensitive content, in a predictable location under /tmp and then prints it back to stdout. In shared or multi-user environments, this creates an unnecessary persistence and disclosure risk because confidential input may remain accessible on disk longer than the user expects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script writes the full fetched article text and derived metadata into a persistent markdown file under /tmp without warning the user or limiting what is stored. If the provided URL points to sensitive or access-controlled content, this can leave local copies of potentially confidential data on disk where other local users, backup processes, or later workflows may access it unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script fetches arbitrary user-supplied URLs with curl, which can cause server-side request forgery behavior in environments where the agent has network access to internal services, cloud metadata endpoints, or other restricted resources. The lack of any warning, validation, or restriction makes this more dangerous in an agent skill context because users may unknowingly cause requests from a more privileged network location than their own.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.