Back to skill

Security audit

ai-article-detector

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it can fetch any URL without safeguards, which could expose internal network resources or exhaust local resources.

Install only if you are comfortable with the skill making outbound requests to URLs supplied to it. Prefer running it in a sandboxed environment with no access to internal networks, and avoid using it on untrusted links until it adds URL allowlisting or private-IP blocking, redirect validation, request timeouts, response-size limits, and pinned dependencies. Treat the AI score as a heuristic, especially outside Chinese-language content.

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

Error
Location
ai-article-detector.js:50
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: ai-article-detector.js, lines 50-61
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: High

Vulnerable Code

js
const response = await fetch(url, {
  headers: {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
  }
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);

const html = await response.text();

Technical Analysis

The URL supplied through the command-line argument is passed to fetch() without validating its protocol, hostname, resolved IP address, destination port, or redirect chain. Although outbound network access is necessary to retrieve an article, unrestricted access to arbitrary network destinations exceeds the minimum privileges needed for this functionality.

An attacker can provide a URL targeting loopback addresses, private network ranges, link-local services, or cloud instance metadata endpoints. Because node-fetch follows redirects by default, an initially public URL may also redirect the request to an internal destination. Destination validation performed only before the initial request would therefore be insufficient.

The retrieved response is parsed and analyzed locally. The reviewed code does not transmit the retrieved article to a fixed third party, but it can still act as a network request proxy into resources accessible from the host.

Attack Path

  1. An attacker supplies a crafted URL as the first command-line argument or passes it to detect().
  2. detect() forwards the value to fetchArticle().
  3. fetchArticle() passes the untrusted URL directly to fetch().
  4. The request reaches an internal service directly, or a public attacker-controlled endpoint redirects it to an internal service.
  5. The application reads the internal response and processes its contents as article text.
  6. Observable output, response status, errors, processing behavior, and ar ...[truncated 771 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse input with the standard URL class and allow only explicitly required protocols, normally https: and optionally http:.
  2. Reject URLs containing embedded credentials or unsupported destination ports.
  3. Resolve the hostname before connecting and reject all loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
  4. Protect against DNS rebinding by ensuring the connection uses the validated address and by checking every resolved address.
  5. Disable automatic redirects or manually process redirects with a strict limit. Revalidate the protocol, hostname, port, and resolved addresses at every redirect.
  6. Prefer an allowlist of approved public domains if arbitrary websites are not essential.
  7. Apply outbound firewall or sandbox rules that prevent the process from accessing local, private, and metadata networks.
  8. Return generic network errors where possible to reduce the usefulness of the application as an internal network oracle.

T09 · Insecure Skill Coding Practices

Warning
Location
ai-article-detector.js:50
Finding

Unbounded Remote Response Consumption Allows Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: ai-article-detector.js, lines 50-61
Vulnerability Type: Uncontrolled Resource Consumption
Risk Level: Medium

Vulnerable Code

js
const response = await fetch(url, {
  headers: {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
  }
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);

const html = await response.text();

Technical Analysis

The remote response is consumed through response.text() without a request timeout, inactivity timeout, response-size limit, or streaming byte cap. This operation buffers the complete response in memory before JSDOM parses it, which can require additional memory proportional to the document size.

A malicious or compromised website can return an extremely large body, stream data indefinitely, or respond very slowly. The process may consequently remain occupied for an excessive period, consume substantial memory, or terminate due to resource exhaustion.

The absence of a body limit is especially significant because the content is subsequently passed to JSDOM, causing another computationally and memory-intensive processing stage.

Attack Path

  1. An attacker supplies a URL under their control.
  2. The application requests the URL with no configured timeout.
  3. The server stalls the connection, streams indefinitely, or sends an excessively large HTML document.
  4. response.text() continues waiting for or buffering the response.
  5. If the response completes, JSDOM performs additional parsing over the oversized content.
  6. The process suffers increased latency, excessive CPU or memory use, or termination.

Impact Assessment

Exploitation can cause local denial of service, degraded host performance, memory exhaustion, and prolonged occupation of the Node.js process. In a shared or repeatedly invoked service environment, concurrent malicious requests could amplify the ...[truncated 220 chars]

Remediation
View remediation

Remediation Suggestions

  1. Use AbortController to enforce a short connection and total-request timeout.
  2. Validate Content-Length when present and reject responses exceeding a documented maximum article size.
  3. Do not rely exclusively on Content-Length, because it may be absent or dishonest. Read the response as a stream and stop after a strict byte limit.
  4. Apply an inactivity timeout while streaming to prevent slow-response attacks.
  5. Reject content types that are not expected article formats, such as non-HTML or non-text responses.
  6. Limit redirect count and apply the same timeout and size controls after every redirect.
  7. Enforce runtime memory, CPU, and concurrency limits through process isolation or container controls.
  8. Avoid passing oversized documents to JSDOM; reject them before parsing.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill claims to analyze article links, but the described or detected behavior does not actually fetch or analyze remote article content. This mismatch can mislead users and calling agents into trusting outputs as if they were derived from a live URL, creating integrity and decision-making risk because results may be fabricated, stale, or based only on embedded samples rather than the requested target.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description and usage text are written as instructions in Chinese, including the core behavior statement about detecting whether an article was AI-generated. There is no indication that users can choose another language or that the skill is intentionally limited to a Chinese-only regional context, which creates a locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file's natural-language comments, declared input/output description, and CLI-facing strings are all written in Chinese, which effectively forces a specific language experience. There is no indication that the skill is region-specific or that users can opt into another language, which matches the locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The documentation states "当前优化语言:中文," which indicates a language-specific constraint. Under the policy, language or locale restrictions should either provide user opt-in/choice or be clearly justified as region-specific; this README does not do so.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified with a caret range, which allows newer minor/patch releases to be installed over time. That weakens build reproducibility and can unexpectedly introduce vulnerable or malicious upstream changes through the supply chain.

Content

Scanner excerpt · package.json (reported line 13)May include surrounding context.

json
"test": "node test-sample.js"
  },
  "dependencies": {
    "node-fetch": "^3.3.2",
    "jsdom": "^23.0.1"
  }
}

Unverifiable Dependency: node-fetch has 3 known advisory(ies) (CVE-2022-0235 (node-fetch forwards secure headers to untrusted sites); CVE-2022-2596 (node-fetch Inefficient Regular Expression Complexity ); CVE-2020-15168 (The `size` option isn't honored after following a redirect in node-fetch)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

node-fetch has known historical advisories, and because the manifest uses a version range rather than an exact pinned release, it is not possible to verify from this file alone whether deployed installs are affected. In a skill that retrieves remote article URLs, a vulnerable HTTP client can increase exposure to header leakage, redirect-related issues, or denial-of-service conditions.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is not pinned to an exact version, so future installs may resolve to different releases. In a package that fetches and parses untrusted article content, supply-chain drift increases risk because parser/networking dependencies are security-sensitive.

Content

Scanner excerpt · package.json (reported line 14)May include surrounding context.

json
},
  "dependencies": {
    "node-fetch": "^3.3.2",
    "jsdom": "^23.0.1"
  }
}

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

All user-facing comments, sample content, and console output are in Chinese, and the file does not offer any language selection or explain that it is intentionally region-specific. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.