Back to skill

Security audit

Content Alchemy

Security checks for vulnerabilities and agentic risk

Overview

This reading skill is useful, but its URL extractor can access local or internal resources and its long-PDF notes persist locally, so it should be reviewed before installation.

Install only if you are comfortable with the skill fetching URLs from the agent's environment and saving long-PDF progress and derived notes on disk. Avoid giving it file://, localhost, private-network, cloud-metadata, or other sensitive internal URLs, avoid --insecure except with explicit trust in the source, and clear ~/.content-alchemy/sessions when working with confidential documents.

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
scripts/extract_web_text.py:121
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/extract_web_text.py, lines 121-126
Vulnerability Type: Server-Side Request Forgery and unbounded response processing
Risk Level: Medium

python
def fetch_html(url: str, timeout: int, insecure: bool) -> str:
    request = Request(url, headers={"User-Agent": USER_AGENT})
    context = ssl._create_unverified_context() if insecure else ssl.create_default_context()
    with urlopen(request, timeout=timeout, context=context) as response:
        charset = response.headers.get_content_charset() or "utf-8"
        return response.read().decode(charset, errors="replace")

Technical Analysis

The user-controlled URL is passed directly to urllib.request.urlopen without validating its scheme, destination address, resolved IP address, or redirect targets. Consequently, the extractor can make requests to loopback interfaces, private networks, link-local services, and cloud instance metadata endpoints.

Scheme validation is also absent. The implementation should explicitly limit input to HTTP and HTTPS rather than relying on the behavior of the URL library. Redirects require independent validation because an initially public URL can redirect to a prohibited internal destination.

The response is consumed using an unrestricted response.read(). The --max-chars option limits extracted text only after the entire HTTP response has been downloaded and decoded, so it does not prevent excessive memory use from a large response.

Attack Path

  1. An attacker supplies a URL that targets an internal resource, such as a loopback service, private-network administrative interface, or link-local metadata endpoint.
  2. The Agent follows the Skill workflow and invokes extract_web_text.py with that URL.
  3. urlopen sends the request from the Agent's execution environment, where the target may be reachable even though it is inaccessible to the attacker.
  4. The internal resp ...[truncated 1109 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the URL before creating the request and permit only http and https.
  2. Reject URLs containing embedded credentials.
  3. Resolve the hostname and reject every address that is loopback, private, link-local, multicast, reserved, or unspecified.
  4. Revalidate the destination after every redirect. Prefer a custom redirect handler that refuses redirects to prohibited hosts or addresses.
  5. Consider an explicit host allowlist when the deployment has a limited set of permitted sources.
  6. Stream the response in bounded chunks and stop after a configured maximum number of bytes. Do not call unrestricted response.read().
  7. Validate the response content type and reject unexpected binary content.
  8. Apply separate connection and total-transfer time limits where supported.
  9. Require explicit user confirmation before accessing non-public or unusual destinations.
  10. Add tests covering loopback addresses, IPv6 loopback, private ranges, link-local addresses, DNS rebinding, redirects to internal services, and oversized responses.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/extract_web_text.py:109
Finding

Documented TLS Verification Bypass Permits Source-Content Tampering

Content
View full analysis

Vulnerability Details

File Location: scripts/extract_web_text.py, lines 109-113 and 121-124
Vulnerability Type: Improper certificate validation
Risk Level: Low

python
    parser.add_argument(
        "--insecure",
        action="store_true",
        help="Disable TLS certificate verification for troubleshooting only",
    )
python
def fetch_html(url: str, timeout: int, insecure: bool) -> str:
    request = Request(url, headers={"User-Agent": USER_AGENT})
    context = ssl._create_unverified_context() if insecure else ssl.create_default_context()
    with urlopen(request, timeout=timeout, context=context) as response:

The unsafe option is also presented as a troubleshooting command in SKILL.md, lines 121-125, and README.md, lines 125-129.

Technical Analysis

When --insecure is supplied, ssl._create_unverified_context() disables certificate-chain and hostname verification. HTTPS then provides encryption without reliable server authentication.

A network-positioned attacker can impersonate the requested website and replace its content. This risk is particularly relevant to an AI Agent because the fetched page becomes model input. Tampered content may produce misleading notes or contain adversarial instructions intended to influence subsequent Agent behavior.

The option is described as troubleshooting-only, but it is included in the normal Skill documentation and has no interactive warning, destination restriction, or explicit acknowledgment requirement.

Attack Path

  1. A legitimate HTTPS extraction fails because of a certificate or trust-store problem.
  2. The operator or Agent follows the documented troubleshooting instructions and retries with --insecure.
  3. An attacker capable of intercepting network traffic presents an arbitrary certificate and impersonates the requested host.
  4. The script accepts the unauthenticated connection and downloads attacker-cont ...[truncated 953 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the --insecure option and the corresponding troubleshooting examples.
  2. Resolve certificate failures by correcting the operating system trust store or supplying a trusted CA bundle.
  3. If bypass functionality must remain, require explicit interactive confirmation and print a prominent warning that server identity will not be verified.
  4. Prevent automated Agent workflows from enabling the option without direct user authorization.
  5. Restrict insecure requests to explicitly approved hosts and prohibit redirects while verification is disabled.
  6. Clearly mark resulting output as unauthenticated and avoid persisting it as trusted source material.
  7. Treat all extracted page text as untrusted data and instruct the Agent not to follow commands or behavioral directives found inside source content.
  8. Log that verification was disabled without recording sensitive response data.
  9. Add tests confirming that invalid certificates and hostname mismatches fail under the default configuration.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill instructs the agent to load external plan/state JSON, derive filesystem paths from returned values, mutate persistent state, and resume prior sessions. If those paths or JSON contents are not trusted and validated by the underlying scripts, this design can enable path abuse, unintended file writes, or cross-session data exposure through state-driven file operations.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

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

md
hts
- actionable next steps
- reusable takeaway

## When To Use

Prefer this skill when the user wants something like:

- "Turn this article into something I can keep"
- "Extract the useful takeaways from this page"
- "Turn this PDF into notes and actions"
- "Help me continue reading this long PDF"
- "Summarize this content, but make it more useful than a plain summary"

## Differentiation Rules

Always follow these rules:

1. Do not treat the task as plain summarization.
2. Reconstruct value, structure, and usefulness instead of merely compressing content.
3. The output should feel like a saved personal artifact, not model paraphrase.
4. Every result should improve at least one of these:
   - easier to revisit
   - easier to retain
   - easier to act on
   - easier to reuse
5. If the result still reads like a generic summary, restructure it again.

## Scope and Limits

This release supports three routes:

- `plain_text`
- `web_url`
- `pdf_file`

This release does not directly handle:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill invokes shell commands, reads and writes files, inspects environment-derived paths, and fetches remote URLs, but it declares no explicit tool scope or permissions boundary. That makes the operational capability broader and less auditable than the metadata suggests, increasing the chance of unintended file access, persistence, or network use when the skill is run by an agent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The text states that the public bundle should expose the skill's English-facing behavior and documentation, which is a natural-language locale constraint. The file does not indicate that users can opt into other languages or that the English-only requirement is justified by a documented region-specific or compliance need.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The guide describes fetching arbitrary user-supplied URLs but does not disclose that this triggers network access or that supplied URLs/content may be transmitted to external systems. This can surprise users, create privacy exposure, and in some implementations may open the door to unsafe URL handling such as access to internal resources if URL validation is weak.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The feature guide states that reading plans, state files, segment outputs, and checkpoint summaries are stored under a persistent local directory, but gives no warning that potentially sensitive document-derived artifacts remain on disk. Users may unknowingly leave confidential source content, summaries, or progress metadata recoverable by other local users, backups, or later processes.

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/extract_pdf_text.py (reported line 71)May include surrounding context.

python
def run_command(args: list[str]) -> subprocess.CompletedProcess[str]:
    return subprocess.run(
        args,
        capture_output=True,
        text=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The human-readable summary is always emitted in Chinese, regardless of user preference or environment. This is a natural-language locale policy issue because the file does not offer a language choice or document a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The user-facing strategy reasons returned by the skill are hard-coded in Chinese across multiple branches, and additional user-facing recommendation strings later in the file are also Chinese-only. This imposes a specific language/locale on users without opt-in or explanation, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This Python file contains hard-coded Chinese natural-language messages in checkpoint_note, and the final human_summary also emits Chinese text. The skill does not offer a language/locale option or document a justified region-specific constraint, which violates the language/locale policy for natural-language behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This is a manifest file, so vague-trigger review applies. The description broadly says the skill can 'Turn articles, web pages, PDFs, and excerpts into structured notes' but does not define specific trigger phrases, activation boundaries, or exclusion conditions, which could lead to unintended invocation for common reading or summarization requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README states that long-PDF reading artifacts are stored persistently under a fixed local path and enables commands to restore prior sessions, but it does not warn users that extracted document text, progress metadata, and summaries may remain on disk after use. For a skill that processes articles, PDFs, and books, this can expose sensitive reading material or derived notes to other local users, backups, or later unintended disclosure, especially when documents contain private or proprietary content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This code writes extracted PDF text and metadata to the path provided via --output, which can affect user data on disk. Although file output is part of the script's functionality, there is no confirmation prompt, print/log disclosure, or inline warning near the write operation about overwriting or creating files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest specifies 'language': 'en', which appears to constrain the skill to English. There is no nearby indication of user opt-in, language choice, or a documented reason for an English-only restriction, so this may violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.