Back to skill

Security audit

Volcseed

Security checks for vulnerabilities and agentic risk

Overview

This skill does the advertised Volcseed image-editing submit/fetch work, but it sends a bearer token to configurable URLs without validating that those URLs are trusted.

Review before installing. Use this only if you trust the source that writes TS_TOKEN and AIZNT_PROXY_URLS, and verify those URLs are HTTPS endpoints controlled by the intended Volcseed/Tianshu service. Treat prompts and image URLs as data that will leave your machine.

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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/client.js:40
Finding

Bearer Token Disclosure Through Unvalidated Configurable Endpoints

Content
View full analysis

Vulnerability Details

File Location: scripts/client.js:4-20, scripts/client.js:40-48, scripts/volcseed.js:50-57, and scripts/volcseed.js:63-68
Vulnerability Type: Unvalidated outbound request destination with sensitive authorization header
Risk Level: High

The endpoint URLs are loaded from AIZNT_PROXY_URLS and used without validating their protocol, hostname, or port. The TS_TOKEN credential is then attached as a Bearer token to requests sent to those endpoints.

Relevant endpoint-loading code from scripts/client.js:4-20:

js
const token = (process.env.TS_TOKEN || '').trim();
if (!token) {
  throw new Error('缺少 TS_TOKEN(天树对话凭证 ts_xxx,对应 skills.entries 的 apiKey)');
}
const raw = process.env.AIZNT_PROXY_URLS;
if (!raw || !String(raw).trim()) {
  throw new Error('缺少 AIZNT_PROXY_URLS(JSON 字符串,与 GET /miniapp/ai/chat/credentials 返回的 aiznt_proxy_urls 一致)');
}
let urls;
try {
  urls = typeof raw === 'string' ? JSON.parse(raw) : raw;
} catch {
  throw new Error('AIZNT_PROXY_URLS 不是合法 JSON');
}
if (!urls || typeof urls !== 'object') {
  throw new Error('AIZNT_PROXY_URLS 必须是对象');
}
return { token, urls };

Relevant authorization and request code from scripts/client.js:40-48:

js
function authHeaders(token, extra = {}) {
  return {
    Authorization: `Bearer ${token}`,
    ...extra,
  };
}

async function fetchJson(url, options = {}) {
  const res = await fetch(url, options);

The configured destinations are used directly in scripts/volcseed.js:50-57:

js
const url = urls.volcseededit_submit;
if (!url) throw new Error('AIZNT_PROXY_URLS 缺少 volcseededit_submit');
const data = await fetchJson(url, {
  method: 'POST',
  headers: authHeaders(token, { 'Content-Type': 'application/json' }),
  body: JSON.stringify({ prompt, image_urls: imageUrls }),
});

The same behavior occurs for result retrieval in scripts/volcseed.js:63-68:

` ...[truncated 2901 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse every configured endpoint with new URL() before issuing a request.
  2. Require the https: scheme and reject plaintext HTTP, embedded URL credentials, fragments, and unexpected ports.
  3. Enforce an explicit allowlist of trusted Volcseed/Tianshu hostnames. Compare normalized hostnames exactly rather than using suffix checks that can accept domains such as trusted.example.attacker.com.
  4. Validate the destination immediately before adding the Authorization header, so future callers cannot bypass validation.
  5. Configure redirects conservatively. Prefer redirect: 'manual', or revalidate every redirect target and never forward authorization headers across origins.
  6. Use a service-specific, least-privileged, short-lived token instead of a broadly reusable credential where supported.
  7. Validate task_id against the service's expected identifier syntax. At minimum, encode replacements with encodeURIComponent() when inserting them into path or query components.
  8. Apply outbound network controls so the Skill can reach only approved service addresses and cannot access loopback, link-local, private, or cloud-metadata endpoints.
  9. Avoid logging credentials or complete sensitive responses, and redact signed URLs or other secrets before displaying errors and results.
  10. Add tests confirming rejection of HTTP URLs, unapproved domains, embedded credentials, deceptive subdomains, unexpected ports, internal addresses, and cross-origin redirects.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documentation indicates it uses environment variables and makes network calls, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a mismatch between documented capabilities and enforceable policy, increasing the risk of over-privileged execution, unintended outbound requests, or access to sensitive credentials without clear user or platform visibility.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This JavaScript file uses Chinese-only natural-language strings in the header comment and all thrown error messages, with no indication that the user can choose another language. That creates a locale/language policy concern because the skill appears to require Chinese for diagnostics and usage feedback without documented opt-in or justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The submit command sends user-provided prompt text and image URL data to a remote endpoint via HTTP POST. In this file there is no confirmation prompt, user-facing warning, or explanatory comment/docstring disclosing that these inputs will be transmitted off-box.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The tagline at L03 is in Chinese while the description at L04 is in English, but the manifest provides no indication of intended locale, user language selection, or justification for this mixed-language presentation. This can create a language/locale policy concern because the skill appears to impose language expectations without explicit user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

Multiple user-facing strings, including usage text and validation errors, are presented only in Chinese. This imposes a fixed language choice on all users without offering locale selection or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.