Back to skill

Security audit

NewsPaper

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local newspaper-rendering service, but it exposes an unauthenticated web server with image generation, persistent output files, unbounded generation parameters, and prompt logging that is under-disclosed.

Install only if you intend to run a local web service and trust the local network environment. Bind it explicitly to 127.0.0.1, add authentication or firewalling before any shared use, disable or tightly limit ComfyUI generation for untrusted callers, avoid sensitive article text or prompts, and treat generated output files and logs as persistent records.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server.js:79
Finding

Unauthenticated Render Endpoint Exposes Internal Image Generation and Persistent File Creation

Content
View full analysis
{ console.log('[INFO] Received render request'); console.log('[INFO] Title:', req.body.title, '| Article count:', req.body.articles?.length || 0); const errors = validateInput(req.body); if (errors.length > 0) { return res.status(400).json({ success: false, errors: errors }); } try { const id = generateId(); // The request can initiate image generation against an internal service. const comfyOptions = req.body.comfyOptions || {}; const imagePromptIndex = findImagePromptArticle(req.body.articles); if (comfyOptions.enabled !== false && imagePromptIndex >= 0) { const article = req.body.articles[imagePromptIndex]; const comfyAvailable = await checkAvailability(); if (comfyAvailable) { const generateOptions = { timeout: comfyOptions.timeout || 120000, interval: comfyOptions.interval || 2000, width: comfyOptions.width || 1024, height: comfyOptions.height || 1024 }; const result = await generateImage(article.imagePrompt, generateOptions); req.body.articles[imagePromptIndex].imageUrl = result.imageUrl; } } const html = template(templateData); const outputPath = path.join(outputDir, `${id}.html`); fs.writeFileSync(outputPath, html, 'utf-8'); res.json({ success: true, id: id, url: `http://localhost:${PORT}/output/${id}.html` }); } catch (error) { res.status(500).json({ success: false, ...[truncated 2131 chars]
Remediation
View remediation
{ console.log(`Service available at http://127.0.0.1:${PORT}`); }); ``` 2. If remote access is required, enforce authentication and authorization on `/render`. 3. Place the service behind a reverse proxy with TLS, request-size limits, authentication, and per-client rate limits. 4. Introduce per-user generation quotas and global concurrency limits. 5. Apply restrictive network policy so only this service can reach the intended ComfyUI instance. 6. Implement expiration and periodic deletion of generated output files. 7. Return externally configured URLs rather than assuming `localhost`. 8. Monitor repeated render requests, failed authentication, generation duration, and output-directory growth. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
server.js:139
Finding

Unbounded Image Generation Parameters Permit Resource Exhaustion

Content
View full analysis
timeout) { throw new Error("ComfyUI generation timeout"); } try { const res = await axios.get( `${COMFY_BASE_URL}/history/${promptId}`, { timeout: 5000 } ); const record = res.data[promptId]; if (record && record.outputs) { const result = extractImageUrl(record.outputs); if (result) { return result; } } } catch (err) { if (err.code !== 'ECONNABORTED' && !err.message.includes('404')) { console.warn('[ComfyUI] Polling error:', err.message); } } await sleep(interval); } } ``` ### Technical Analysis The request body directly controls `width`, `height`, `timeout`, and `interval`. The implementation does not verify that these values are finite numbers or that ...[truncated 1686 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
templates/newspaper.html:286
Finding

Caller-Controlled Image URLs Enable Persistent External Tracking

Content
View full analysis
{{headline}} {{/if}} {{#if imageUrl}}
{{headline}}
{{/if}} ``` ### Technical Analysis The server passes each complete caller-supplied article object into the Handlebars template. Although the documented request model only describes `headline`, `body`, and `imagePrompt`, the implementation does not remove additional properties. A caller can therefore supply an `imageUrl` property directly. Handlebars HTML escaping prevents a straightforward attribute breakout, but it does not establish whether the URL is trusted. When a generated newspaper is viewed, the browser can request any attacker-selected HTTP or HTTPS image URL embedded in the page. This creates a persistent external-request primitive. It is not server-side request forgery because the browser, rather than the server, loads the caller-supplied URL. It can nevertheless be used as a tracking pixel or to expose access metadata. ### Attack Path 1. The attacker submits an article containing an undocumented property such as: ```json { "headline": "Shared report", "body": "Content", "imageUrl": "https://attacker.example/track?id=unique-recipient" } ``` 2. Input validation accepts the article because unknown properties are not rejected. 3. The full article object is supplied to the template. 4. The generated file persists the attacker-cont ...[truncated 835 chars]
Remediation
View remediation
({ headline: article.headline, body: article.body, imagePrompt: article.imagePrompt })); ``` 2. Store generated image URLs separately from caller data and attach them only after a successful trusted ComfyUI response. 3. Reject unknown request properties through JSON Schema validation with `additionalProperties: false`. 4. Validate all image URLs against an explicit allowlist of schemes, hosts, ports, and paths. 5. Prefer proxying or copying trusted generated images into local storage rather than embedding external URLs. 6. Add a restrictive Content Security Policy, for example: ```http Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; img-src 'self' http://127.0.0.1:8000; base-uri 'none'; frame-ancestors 'none' ``` 7. Set an appropriate `Referrer-Policy`, such as `no-referrer`. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
comfy-client.js:196
Finding

Full Image Prompts Are Written to Logs Contrary to the Documented Privacy Policy

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (22)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill instructs an agent to send user-provided article text and optional image prompts to local HTTP services, but it does not require explicit user consent or warn that content will be transmitted to other processes/services. Even though the destination is localhost, this is still cross-service data disclosure and can expose sensitive user content to a renderer or image-generation backend the user did not intend to involve.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The skill explicitly performs an HTTP POST to a local service and includes structured article content in the request body. This is an external transmission from the agent to another service boundary; if users are unaware, sensitive content may be disclosed, and because the protocol is plain HTTP, local interception or unintended routing through altered localhost mappings/proxies can increase risk.

Content

Scanner excerpt · AGENT.md (reported line 186)May include surrounding context.

第五步:调用 API

javascript
const response = await fetch('http://localhost:3000/render', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README advertises automatic AI image generation but does not disclose whether prompts or related article content are sent to an external model provider. Users may unknowingly submit sensitive or proprietary material for third-party processing, creating privacy and data-handling risk even if the underlying feature is expected behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README states that the service returns a URL for viewing rendered pages but does not warn that generated content may become accessible through a predictable or shareable endpoint. If users render sensitive news drafts, internal reports, or personal content, this could expose data to unintended viewers.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The markdown explicitly instructs users to use English descriptions for imagePrompt, which imposes a language constraint as a policy matter. The file does not offer a language choice, opt-in, or a documented justification for why English is required.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The skill instructs the agent to send user-supplied article content to an HTTP service on localhost:3000, which is an external transmission from the agent context to another process. Even though the destination is local, it still exports potentially sensitive user content to a separate service, and the documentation only partially mitigates this by advising not to include sensitive data.

Content

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

调用示例

javascript
const response = await fetch('http://localhost:3000/render', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · AGENT.md (reported line 186)May include surrounding context.

调用示例

javascript
const response = await fetch('http://localhost:3000/render', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

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

调用示例

javascript
const response = await fetch('http://localhost:3000/render', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The function transmits the full user prompt to an external HTTP service via axios.post to COMFY_BASE_URL without any in-code consent, minimization, or privacy notice, and it also logs the prompt to the console. Prompts can contain sensitive user data, and because the default endpoint uses plain HTTP, the data may be exposed to operators, logs, or network interception depending on deployment context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file uses Chinese-only natural-language strings throughout comments, logs, validation errors, API descriptions, and startup messages, with no indication that the skill is region-specific or that users can opt into another language. This creates a language/locale policy issue because the skill effectively forces one locale without documented justification or user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document instructs the agent to generate '1 个英文提示词' and repeats '使用英文' as a requirement for prompts. This imposes a language constraint in the skill instructions without an explicit opt-in or documented justification, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

SQP-3 applies to natural-language policy violations in all file types. The README explicitly says users need to provide image descriptions in English, which imposes a language constraint without opt-in, alternative language support, or a documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This repeats the same language-policy issue in another part of the file. The README mandates English descriptions for image generation and does not offer a language choice or explain a justified regional/compliance constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

Comments, log messages, and function descriptions consistently use Chinese, which can impose a language expectation on users or operators without opt-in. The file does not indicate that this is a region-specific or Chinese-only skill, nor does it provide an alternative language option.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency uses a caret range instead of an exact pinned version, so installs may resolve to different releases over time. This weakens reproducibility and can silently introduce vulnerable or malicious package updates into the build, especially for a service component.

Content

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

json
"dev": "node server.js"
  },
  "dependencies": {
    "axios": "^1.14.0",
    "express": "^4.18.2",
    "handlebars": "^4.7.8"
  }

Unverifiable Dependency: axios has 16 known 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), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Axios has multiple known advisories, and because the manifest does not pin an exact version, it is impossible to verify from this file whether the installed release is affected. In an AI rendering service, a vulnerable HTTP client could increase exposure to SSRF, proxy-bypass, request smuggling, or credential leakage depending on how requests are made elsewhere in the skill.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The express dependency is not pinned to a specific version, allowing npm to install newer matching versions automatically. This creates supply-chain risk and undermines deterministic builds, which is a real security weakness even if no exploit is immediately present in this file.

Content

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

json
},
  "dependencies": {
    "axios": "^1.14.0",
    "express": "^4.18.2",
    "handlebars": "^4.7.8"
  }
}

Unverifiable Dependency: express has 5 known advisory(ies) (CVE-2024-10491 (Express ressource injection); CVE-2014-6393 (No Charset in Content-Type Header in express); CVE-2024-9266 (Express Open Redirect vulnerability) +2 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
87% confidence
Finding

Express has known security advisories, and the floating version means the actual installed package cannot be validated from the manifest alone. Since this is a server application, a vulnerable web framework could directly affect request handling, redirects, header behavior, or injection exposure, making the context somewhat more sensitive.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Handlebars is declared with a floating caret range, so the installed version may change across environments or future installs. Because templating libraries have had serious RCE/XSS issues historically, leaving the version unpinned increases exposure to supply-chain and regression risk.

Content

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

json
"dependencies": {
    "axios": "^1.14.0",
    "express": "^4.18.2",
    "handlebars": "^4.7.8"
  }
}

Unverifiable Dependency: handlebars has 16 known advisory(ies) (GHSA-2cf5-4w76-r9qv (Arbitrary Code Execution in handlebars); CVE-2026-33916 (Handlebars.js has Prototype Pollution Leading to XSS through Partial Template In); CVE-2026-33937 (Handlebars.js has JavaScript Injection via AST Type Confusion) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

Handlebars has a history of severe issues including template-based code execution and XSS, and the unpinned version prevents determining whether a safe release is installed. In a rendering service, a vulnerable templating engine is more dangerous because attacker-controlled content may be rendered, potentially turning library flaws into server-side code execution or client-side script injection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The HTML root sets lang="zh-CN", which fixes the output locale to Simplified Chinese. This is a natural-language/locale policy concern because the template does not indicate any user opt-in or configurable language selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The visible labels AI 生成报纸 and 本内容由 AI 生成 are fixed Chinese strings in the template. Because the template provides no alternative language path or opt-in, it imposes a specific language on generated output.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
comfy-client.js:4