Back to skill

Security audit

Image Gen Low Cost

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it advertises, but it needs Review because it can send prompts, image URLs, and API tokens to arbitrary or unsafe API endpoints.

Install only if you trust the selected API provider and understand that prompts, image URLs, and bearer tokens may leave your machine. Prefer a dedicated IMGEN_TOKEN, avoid relying on OPENAI_API_KEY, use only trusted HTTPS endpoints, and avoid private/internal image URLs or sensitive prompts.

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/imgen.js:103
Finding
Bearer Tokens and Sensitive Request Data Can Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/imgen.js:24, 103-109, 151-153` **Vulnerability Type**: Insecure transport of credentials and sensitive data **Risk Level**: Medium ### Vulnerable Code ```js const DEFAULT_API_URL = process.env.IMGEN_API_URL || 'https://api.laozhang.ai/v1/chat/completions'; ``` ```js function httpPost(urlString, headers, body) { return new Promise((resolve, reject) => { const url = new URL(urlString); const client = url.protocol === 'https:' ? https : http; const options = { hostname: url.hostname, port: url.port || (url.protocol === 'https:' ? 443 : 80), path: url.pathname + url.search, method: 'POST', headers: { 'Content-Type': 'application/json', ...headers } }; ``` ```js const result = await httpPost(DEFAULT_API_URL, { 'Authorization': `Bearer ${token}` }, body); ``` ### Technical Analysis The API endpoint can be changed through the `IMGEN_API_URL` environment variable. The HTTP request implementation explicitly supports both HTTPS and unencrypted HTTP without requiring an additional security override or warning. When an endpoint beginning with `http://` is configured, the CLI transmits the following information without transport encryption: - The bearer API token in the `Authorization` header. - User-provided image-generation prompts. - Image-editing instructions. - Source image URLs included in editing requests. - Model and output-size parameters. Bearer tokens provide access to the associated API account to any party possessing them. Plaintext HTTP does not protect request headers or bodies from network interception or modification. The documented default endpoint uses HTTPS, so exploitation requires the endpoint to be changed to HTTP, whether intentionally, through unsafe setup instructions, or through manipulation of the process environment. ### Attack Path 1. A user or automation environment sets `IMGEN_API_URL` to an e ...[truncated 912 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject non-HTTPS API endpoints by default: ```js const url = new URL(urlString); if (url.protocol !== 'https:') { throw new Error('API endpoints must use HTTPS'); } ``` 2. If plaintext HTTP is needed for local development, require an explicit opt-in such as `IMGEN_ALLOW_INSECURE_HTTP=1` and restrict its use to loopback addresses. 3. Validate the endpoint before retrieving the token so credentials are never prepared for an unsafe destination. 4. Consider displaying the normalized endpoint hostname before the first credentialed request. 5. Document that bearer credentials must only be sent to trusted HTTPS endpoints. 6. Add tests confirming that `http://` endpoints are rejected and that malformed or unsupported URL schemes cannot receive credentials. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/imgen.js:87
Finding
Unvalidated API-Controlled Image Downloads Permit Server-Side Request Forgery and Memory Exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/imgen.js:87-97, 159-161, 189, 246-248, 275, 285-297` **Vulnerability Type**: Server-side request forgery and unbounded response buffering **Risk Level**: Medium ### Vulnerable Code ```js function httpGet(url) { return new Promise((resolve, reject) => { const client = url.startsWith('https') ? https : http; client.get(url, (res) => { const chunks = []; res.on('data', chunk => chunks.push(chunk)); res.on('end', () => resolve(Buffer.concat(chunks))); res.on('error', reject); }).on('error', reject); }); } ``` ```js const urlMatch = content.match(/!\[.*?\]\((https?:\/\/[^)]+)\)/); const base64Match = content.match(/!\[.*?\]\((data:image\/[^;]+;base64,([^)]+))\)/); if (urlMatch) { imageUrl = urlMatch[1]; } else if (base64Match) { base64Data = base64Match[2]; } else { imageUrl = result.data?.[0]?.url; } ``` ```js } else { console.log(imageUrl); await downloadImage(imageUrl, outputPath); } ``` ```js const urlMatch = content.match(/!\[.*?\]\((https?:\/\/[^)]+)\)/); const base64Match = content.match(/!\[.*?\]\((data:image\/[^;]+;base64,([^)]+))\)/); if (urlMatch) { resultUrl = urlMatch[1]; } else if (base64Match) { base64Data = base64Match[2]; } else { resultUrl = result.data?.[0]?.url; } ``` ```js async function downloadImage(url, outputPath) { try { const dir = path.dirname(outputPath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } const buffer = await httpGet(url); fs.writeFileSync(outputPath, buffer); console.error(`✓ Saved: ${outputPath}`); } catch (err) { console.error('Download failed:', err.message); } } ``` ### Technical Analysis Image URLs are extracted from the remote API response and automatically fetched from the user's machine when saving is enabled. The downloader does not validate the destination hostname or resolved IP address. Consequently, a malicious or com ...[truncated 2690 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse download targets with the standard `URL` class and allow only HTTPS. 2. Resolve the hostname before connecting and reject all loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges. 3. Explicitly block common cloud metadata destinations, including link-local metadata addresses and provider-specific metadata hostnames. 4. Prefer an allowlist of trusted image-delivery domains associated with the selected API provider. 5. If redirects are implemented, validate the destination again after every redirect to prevent redirect-based filter bypass. 6. Set strict connection, headers, and body timeouts. 7. Enforce a maximum response size while streaming rather than buffering the complete response: ```js const MAX_IMAGE_BYTES = 20 * 1024 * 1024; let received = 0; res.on('data', chunk => { received += chunk.length; if (received > MAX_IMAGE_BYTES) { res.destroy(new Error('Image exceeds maximum permitted size')); return; } chunks.push(chunk); }); ``` 8. Require a successful HTTP status code and validate an expected image MIME type before writing the response. 9. Stream validated content directly to a safely opened file where practical, deleting partial files on failure. 10. Add tests covering loopback, private IPv4, private IPv6, link-local, DNS rebinding, oversized responses, slow responses, invalid MIME types, and redirect chains. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Ae1

High
Category
analysis-evasion
Content
chmod +x scripts/imgen.js
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README instructs users to submit prompts and image URLs to a third-party API service but does not disclose that user content will be transmitted off-host. This can lead users to unknowingly send sensitive text, private image URLs, or proprietary content to a remote provider, creating privacy, confidentiality, and compliance risks.

External Transmission

Medium
Category
Data Exfiltration
Content
## 快速开始

```bash
# 1. 获取 token:访问 https://api.laozhang.ai/register/?aff_code=lfa0 注册

# 2. 配置 token
imgen config --token YOUR_API_TOKEN
Confidence
88% confidence
Finding
The documentation directs users to register with and obtain a token from an external service, indicating reliance on a third-party endpoint for operation. Without prominent trust, privacy, and data-flow disclosures, users may expose credentials, prompts, or image-related data to an external provider they did not fully evaluate.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill documents use of environment variables and token/config handling, but it does not declare any explicit tool scope or permissions boundaries. That creates ambiguity about what runtime capabilities the skill expects and increases the chance an agent exposes environment data or executes the skill with broader access than necessary.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger words include very broad everyday phrases like '生成图片' and '画图', which can cause the skill to activate unintentionally in normal conversation. Mis-triggering is dangerous here because the skill can prompt users to configure tokens, send prompts or image URLs to external APIs, and potentially incur cost or leak data to third-party endpoints.

External Transmission

Medium
Category
Data Exfiltration
Content
### 1. 获取 API Token

访问 [https://api.laozhang.ai/register/?aff_code=lfa0](https://api.laozhang.ai/register/?aff_code=lfa0) 注册,在控制台获取 token。新注册自动获得 $0.5 开发测试额度。

### 2. 配置 Token
Confidence
93% confidence
Finding
The skill directs users to register for and use a third-party API service, which will receive prompts, image references, and tokens. Because this is an external transmission path tied to account creation and credential use, sensitive user content may be disclosed to an external provider with limited trust guarantees.

External Transmission

Medium
Category
Data Exfiltration
Content
## API 端点

默认使用老张 API (`https://api.laozhang.ai/v1/chat/completions`)。

```bash
# 切换到其他 OpenAI 兼容端点
Confidence
97% confidence
Finding
The documented default API endpoint sends requests to a non-default third-party service, so user prompts, image-edit URLs, and authentication tokens are transmitted off-platform. In the context of an agent skill, this is more dangerous because activation may happen automatically and users may not realize their content is being routed to an external vendor.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# 切换到其他 OpenAI 兼容端点
export IMGEN_API_URL=https://api.openai.com/v1/chat/completions

# 使用其他兼容服务
export IMGEN_API_URL=https://your-api-endpoint.com/v1/chat/completions
Confidence
91% confidence
Finding
Allowing a fully user-configurable API URL means prompts and tokens can be sent to arbitrary OpenAI-compatible endpoints. This increases the risk of credential exfiltration or accidental transmission to malicious or mistyped domains, especially since the skill itself warns that tokens may be sent to the wrong endpoint.

External Transmission

Medium
Category
Data Exfiltration
Content
// Default API endpoint (OpenAI-compatible)
// Default to laozhang API as documented in SKILL.md
const DEFAULT_API_URL = process.env.IMGEN_API_URL || 'https://api.laozhang.ai/v1/chat/completions';

// Available models with pricing (laozhang API)
// Sorted by price, cheapest first (sora_image is default)
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 CLI allows the outbound API destination to be fully overridden via IMGEN_API_URL, and then sends the user's prompt plus bearer token to that endpoint. In a skill/agent context, this expands behavior from 'generate images' to arbitrary authenticated POSTs to attacker-controlled services, which can enable credential exfiltration or unintended data disclosure.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The edit flow sends user-provided image URLs and prompts to a remote API, which may disclose private images, internal URLs, or sensitive prompt contents to a third party. In an agent setting, users may not realize that referenced images and instructions are being transmitted off-system for processing.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The natural-language instructions and examples are presented only in Chinese, which can amount to a forced language choice if the skill is intended for a general audience. There is no indication that the tool is region-specific or that alternative language documentation is available.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
L003 的描述全文使用中文,且未说明是否支持其他语言或允许用户按偏好选择语言。根据规则,若技能在自然语言层面强制特定语言而无用户选择,可能构成语言/locale 策略问题。

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
The preset text "Convert to Chinese ink wash painting style" embeds a specific locale/cultural language choice directly in the natural-language instruction. There is no indication of user opt-in or alternative locale phrasing, so this can be read as imposing a language/locale-specific preference.

Context-Inappropriate Capability

Low
Confidence
89% confidence
Finding
The tool implicitly consumes OPENAI_API_KEY, which is a broader, generic credential not specific to this CLI or provider. In shared agent environments this can cause accidental credential reuse and exposure to the configured third-party endpoint, especially when IMGEN_API_URL is also user-configurable.

Static analysis

No suspicious patterns detected.