Back to skill

Security audit

Ai Content Repurposer

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a legitimate AI content repurposing tool, but it has review-worthy weaknesses that can fetch internal URLs and write batch output outside the chosen folder.

Install only if you are comfortable sending processed content to OpenAI and fetching blog URLs from this environment. Avoid processing confidential or regulated content without approval, do not run batch configs from untrusted sources, and prefer an updated version that blocks private/internal URLs, validates redirects, limits response size, sanitizes batch job names, and updates vulnerable dependencies.

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
src/converter.js:219
Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery## Vulnerability Details **File Location**: `bin/cli.js:69-71`, `bin/cli.js:110-112`, and `src/converter.js:219-225` **Vulnerability Type**: Server-Side Request Forgery **Risk Level**: High The blog conversion commands accept an arbitrary value beginning with `http` and pass it directly to an unrestricted Axios request. ```javascript // bin/cli.js:69-71 if (source.startsWith('http')) { console.log('📥 Fetching blog content...'); content = await converter.fetchBlogContent(source); } ``` The same behavior is present in the LinkedIn conversion command: ```javascript // bin/cli.js:110-112 if (source.startsWith('http')) { console.log('📥 Fetching blog content...'); content = await converter.fetchBlogContent(source); } ``` The destination is fetched without validating its host, resolved IP address, port, or redirect chain: ```javascript // src/converter.js:219-225 async fetchBlogContent(url) { try { const response = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' }, timeout: 10000 }); ``` ### Technical Analysis Checking only whether a value starts with `http` is not a security boundary. The code does not parse the URL using a strict URL parser or limit requests to public blog hosts. Consequently, callers can request loopback, private-network, link-local, or cloud metadata destinations. Axios also follows redirects by default. An initially public URL can therefore redirect to an internal destination unless every redirect target is independently validated. The timeout limits request duration but does not prevent access to sensitive network locations. No response-size limit is configured either, allowing a hostile endpoint to return an excessively large body. The fetched response is parsed as article content and then supplied to the OpenAI transformation method. This can cause information obtained from an internal service to leave the local environment ...[truncated 1510 chars]
Remediation
## Remediation Suggestions - Parse destinations with the standard `URL` class and permit only explicit `http:` and `https:` protocols. - Reject URLs containing credentials, ambiguous host representations, or unsupported ports. - Resolve the hostname before connecting and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges for both IPv4 and IPv6. - Disable automatic redirects or validate the scheme, hostname, resolved address, and port of every redirect target. - Prefer an explicit allowlist of trusted blog domains when the deployment permits it. - Set conservative `maxContentLength` and `maxBodyLength` limits. - Restrict response content types to expected textual or HTML formats. - Run network fetching in a sandbox with no access to internal services or metadata endpoints. - Require explicit user confirmation before transferring fetched content to OpenAI. - Add tests covering loopback addresses, private IP addresses, IPv6 literals, alternative numeric IP representations, DNS rebinding, and redirect-based bypasses.

T09 · Insecure Skill Coding Practices

Error
Location
bin/cli.js:242
Finding
Batch Job Name Path Traversal Allows Writes Outside the Output Directory## Vulnerability Details **File Location**: `bin/cli.js:242-277` **Vulnerability Type**: Path Traversal and Arbitrary File Overwrite **Risk Level**: High Batch job names are read from a JSON configuration file and incorporated directly into output paths. ```javascript // bin/cli.js:242-277 const config = JSON.parse(fs.readFileSync(configFile, 'utf-8')); const converter = new ContentConverter(); // Create output directory if (!fs.existsSync(options.outputDir)) { fs.mkdirSync(options.outputDir, { recursive: true }); } console.log(`\n🚀 Batch processing ${config.jobs.length} jobs...\n`); for (const [index, job] of config.jobs.entries()) { console.log(`[${index + 1}/${config.jobs.length}] Processing: ${job.name}`); try { let result; const outputFile = path.join(options.outputDir, `${job.name}.json`); switch (job.type) { case 'youtube-to-shorts': result = await converter.youtubeToShortForm(job.content, job.platform || 'tiktok'); break; case 'blog-to-twitter': result = await converter.blogToTwitterThread(job.content, job.tweetCount || 7); break; case 'blog-to-linkedin': result = await converter.blogToLinkedIn(job.content, job.tone || 'thought-leadership'); break; case 'podcast-to-summary': result = await converter.podcastToSummary(job.content); break; default: console.log(` ⚠️ Unknown job type: ${job.type}`); continue; } fs.writeFileSync(outputFile, JSON.stringify(result, null, 2)); ``` ### Technical Analysis `path.join` normalizes parent-directory components but does not enforce containment beneath `options.outputDir`. A job name containing components such as `../../target` produces a final path outside the intended output directory. The code does not restrict `job.name` to a basename, compare the resolved destination against the resolved out ...[truncated 1574 chars]
Remediation
## Remediation Suggestions - Restrict `job.name` to a conservative basename pattern, such as letters, numbers, underscores, and hyphens. - Explicitly reject `/`, backslashes, null bytes, absolute paths, and `..` path components. - Resolve both the output directory and candidate destination before writing. - Verify that the candidate path starts with the resolved output-directory path followed by the platform path separator. - Use `path.basename(job.name)` only as defense in depth, not as the sole validation mechanism. - Open output files with exclusive creation semantics when overwriting is not explicitly requested. - Refuse to follow symbolic links or verify the real parent directory before writing in hostile multi-user environments. - Validate the complete batch configuration against a strict JSON schema. - Add tests for parent traversal, nested traversal, absolute-looking names, platform-specific separators, symbolic-link escapes, and collisions with existing files.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (20)

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
94% confidence
Finding
The lockfile pins axios 1.13.6, and the supplied advisories include high-risk issues such as SSRF-related NO_PROXY bypasses and prototype-pollution-assisted request/response manipulation. In a skill that fetches and repurposes remote content, an HTTP client flaw is especially relevant because untrusted URLs, redirects, proxy settings, or crafted responses may be part of normal operation.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
86% confidence
Finding
form-data 4.0.5 is flagged for CRLF injection via unescaped multipart field names and filenames. If any part names or filenames are derived from untrusted input, this can corrupt multipart boundaries or inject unintended headers/content into outbound requests, which is dangerous in automation that uploads or relays content.

Known Vulnerable Dependency: undici==7.24.3 — 12 advisory(ies): CVE-2026-6733 (undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse); CVE-2026-13697 (undici vulnerable to cross-user information disclosure and parse-time crash via ); CVE-2026-16728 (undici vulnerable to downstream response desynchronization via retry interceptor) +9 more

High
Category
Supply Chain
Confidence
88% confidence
Finding
undici 7.24.3 is reported with multiple high-severity HTTP parsing and connection-reuse issues, including response desynchronization and information disclosure. Because this project appears to retrieve external content for repurposing, malformed or attacker-controlled upstream responses could potentially poison request handling, mix responses, or expose data across requests.

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding
This package declares axios with a broad range (^1.6.0), and the analyzer indicates resolution to a version with multiple published security advisories, including SSRF- and MITM-related issues. Because this skill is explicitly built to fetch and transform external content, vulnerable HTTP client behavior is more dangerous here than in an offline-only tool.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The code sends user-provided transcripts, blog content, and prompts to an external AI API, which is a real data exfiltration/privacy boundary crossing. In skill contexts without declared scope, consent, or data-handling notice, this can expose sensitive user content to a third party and create compliance risk.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The guide instructs users to configure an OPENAI_API_KEY for AI-powered transformations, but it does not warn that supplied content may be sent to an external AI service when that mode is enabled. In markdown documentation, omission of warnings about potential data transmission to third-party services is a user-disclosure gap.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README instructs users to provide URLs, transcripts, and other content to a tool that requires an OpenAI API key, but it does not clearly disclose that submitted content may be transmitted to external AI providers. This creates a privacy and compliance risk because users may unknowingly send proprietary, personal, or confidential material off-system.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documented batch-processing feature encourages sending multiple content items in one operation but provides no warning that this may result in large-scale transmission of user content and generated outputs to external AI services. That omission increases the chance of accidental bulk disclosure of confidential data and can amplify privacy, contractual, or regulatory impact.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill requires an OpenAI API key and describes AI-powered transformations, which strongly implies that user-provided transcripts, blog content, or podcast text may be transmitted to an external third-party service. Because the description does not clearly warn users that their content may leave the local environment, users could unknowingly submit sensitive or proprietary material, creating a privacy and data-governance risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The manifest declares an OPENAI_API_KEY requirement, which strongly implies user content will be sent to an external AI provider, but the manifest does not warn users that supplied blog posts, podcast content, or other potentially sensitive material may leave the local environment. In a content-repurposing skill, users may upload unpublished marketing copy, client materials, or proprietary media transcripts, so missing disclosure can lead to unintentional data exposure and poor consent/privacy posture.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
With no manifest available, there is no documented justification for accessing process environment variables. Reading OPENAI_API_KEY is a real capability involving credential access, which goes beyond purely local content transformation logic and is not otherwise declared in the provided context.

External Transmission

Medium
Category
Data Exfiltration
Content
constructor(options = {}) {
    this.apiKey = options.apiKey || process.env.OPENAI_API_KEY;
    this.model = options.model || 'gpt-4';
    this.baseUrl = 'https://api.openai.com/v1';
  }

  /**
Confidence
60% 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
94% confidence
Finding
The function fetches arbitrary user-supplied URLs over the network with axios and no allowlist or private-address restrictions. This can be abused for SSRF-style access to internal services or sensitive network resources if an attacker can control the URL input.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Fetched blog content is later designed to be transformed by the AI workflow, but there is no user-facing warning that externally retrieved content may be transmitted to another service. This lack of transparency increases privacy and consent risk, especially if the fetched page contains private or licensed material.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The implementation transmits prompts and user content to an external AI service without any user-visible notice or consent mechanism. Even if expected functionally, undisclosed third-party transfer of potentially sensitive text is a security and privacy weakness.

Missing User Warnings

Low
Confidence
80% confidence
Finding
This markdown file includes a command that accepts a public URL as input, which implies a network request, but the quick-start text does not disclose that the tool may contact external sites when run this way. For markdown files, user-facing documentation should warn about behaviors that can affect privacy or system/network exposure.

Known Vulnerable Dependency: follow-redirects==1.15.11 — 1 advisory(ies): CVE-2026-40895 (follow-redirects leaks Custom Authentication Headers to Cross-Domain Redirect Ta)

Low
Category
Supply Chain
Confidence
84% confidence
Finding
follow-redirects 1.15.11 is flagged for leaking custom authentication headers across cross-domain redirects. If this skill makes authenticated outbound requests, an attacker controlling a redirect target could capture bearer tokens or API keys, though the practical impact depends on whether such headers are used.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"author": "OpenClaw",
  "license": "MIT",
  "dependencies": {
    "commander": "^11.0.0",
    "axios": "^1.6.0",
    "cheerio": "^1.0.0-rc.12"
  },
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"license": "MIT",
  "dependencies": {
    "commander": "^11.0.0",
    "axios": "^1.6.0",
    "cheerio": "^1.0.0-rc.12"
  },
  "engines": {
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The constructor reads OPENAI_API_KEY from process.env, which is access to a sensitive credential source. The file contains no warning, comment, or user-facing notice explaining that the skill depends on and reads an environment-stored API key.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/converter.js:11