Back to skill

Security audit

商品短视频广告 Product Video Ad

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it allows broad network fetching and one provider endpoint override that could expose credentials or internal network resources in unsafe configurations.

Review before installing if you will run storyboards or brand files from untrusted sources. Prefer local reference images or trusted HTTPS image hosts, avoid custom ARK_BASE_URL unless you fully control it, use a fresh output directory per run, and isolate provider credentials from unrelated projects or untrusted npm execution.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib/providers.mjs:23
Finding
Unrestricted Remote URL Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/providers.mjs:23-43`, `scripts/lib/providers.mjs:147-151`, and `scripts/gen.mjs:220-233` **Vulnerability Type**: Server-Side Request Forgery and unbounded remote content retrieval **Risk Level**: Medium ### Vulnerable Code ```js const isUrl = (s) => /^https?:\/\//i.test(s) const MIME = { '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.png': 'image/png', '.webp': 'image/webp', '.gif': 'image/gif', } const mimeOf = (p) => MIME[path.extname(p).toLowerCase()] || 'image/jpeg' async function asBase64(p) { if (isUrl(p)) { const r = await fetch(p) if (!r.ok) throw new Error(`拉取参考图失败 ${r.status}: ${p}`) return Buffer.from(await r.arrayBuffer()).toString('base64') } return (await readFile(p)).toString('base64') } const asDataUri = async (p) => isUrl(p) ? p : `data:${mimeOf(p)};base64,${await asBase64(p)}` ``` The OpenAI provider independently retrieves user-supplied image URLs: ```js for (const p of req.images) { const buf = isUrl(p) ? Buffer.from(await (await fetch(p)).arrayBuffer()) : await readFile(p) fd.append('image[]', new Blob([buf], { type: mimeOf(p) }), path.basename(p)) } ``` Provider-returned output URLs are also downloaded without destination validation: ```js async function persist(files, savePath, req) { if (!files?.length) return [] const out = [] for (const [i, f] of files.entries()) { let target if (savePath) { const ext = path.extname(savePath) || f.ext || '.jpg' const base = savePath.slice(0, savePath.length - path.extname(savePath).length) target = files.length > 1 ? `${base}-${i + 1}${ext}` : `${base}${ext}` } else { target = path.join('output', `${Date.now()}-${i + 1}${f.ext || '.jpg'}`) } await mkdir(path.dirname(target), { recursive: true }) const buf = f.buffer || Buffer.from(await (await fetch(f.url)).arrayBuffer()) await writeFile(target, buf) out.push(target) } return o ...[truncated 2746 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Default to accepting local reference files only. 2. Require an explicit option, such as `--allow-remote-images`, before fetching remote images. 3. If remote images are necessary, enforce an allowlist of trusted HTTPS hostnames. 4. Resolve the target hostname before every request and reject: - Loopback addresses. - Link-local addresses. - Private IPv4 and IPv6 ranges. - Multicast and reserved ranges. - Cloud metadata addresses. 5. Disable redirects or validate the hostname and resolved address after every redirect. 6. Reject redirects that change from HTTPS to HTTP. 7. Apply strict connection and response timeouts. 8. Stream responses while enforcing a maximum byte count instead of calling `arrayBuffer()` without a limit. 9. Validate `Content-Type` and inspect file signatures before treating a response as media. 10. Apply the same URL validation policy to provider-returned output URLs. 11. Consider requiring provider output URLs to match documented provider-owned domains. 12. Avoid forwarding remotely fetched content to cloud providers unless the user is clearly informed and has approved that transfer. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib/providers.mjs:287
Finding
Configurable Ark Endpoint Can Receive the Ark API Credential<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/providers.mjs:287-301` **Vulnerability Type**: Credential disclosure through an unrestricted API endpoint override **Risk Level**: Medium ### Vulnerable Code ```js const ark = { id: 'ark', kind: 'http', hasCredentials: () => Boolean(env.ARK_API_KEY), model: () => env.GEN_MODEL_ARK || env.ARK_MODEL, describe(req) { return `POST ${env.ARK_BASE_URL || 'https://ark.cn-beijing.volces.com/api/v3'}/images/generations model=${ark.model() || '<需设 ARK_MODEL>'}` }, async run(req) { if (!ark.model()) throw new Error('火山方舟需指定模型:export ARK_MODEL=<你开通的 seedream 模型 ID>') const base = env.ARK_BASE_URL || 'https://ark.cn-beijing.volces.com/api/v3' const body = { model: ark.model(), prompt: req.prompt, size: req.size || '2K', response_format: 'url', watermark: false, } if (req.images?.length) body.image = await Promise.all(req.images.map(asDataUri)) const j = await postJson(`${base}/images/generations`, body, { authorization: `Bearer ${env.ARK_API_KEY}` }, req.timeoutMs) ``` ### Technical Analysis The Ark provider permits the complete API base URL to be replaced through `ARK_BASE_URL`. The value is used directly as the request destination, while `ARK_API_KEY` is unconditionally attached as a Bearer credential. There is no validation that: - The endpoint uses HTTPS. - The endpoint belongs to an approved Ark or Volcengine domain. - The endpoint has the expected origin. - Redirects remain on the trusted origin. Environment variables are normally controlled by the user or system administrator. However, they may also be influenced through untrusted launch wrappers, CI configuration, workspace environment files, shell initialization, or orchestration settings. If an attacker can alter `ARK_BASE_URL` but cannot directly read `ARK_API_KEY`, this behavior provides a route for capturing the credential. The default endpoint is the expected Ark HTTPS endpoin ...[truncated 1402 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `ARK_BASE_URL` support if custom Ark-compatible endpoints are not essential. 2. Otherwise, enforce HTTPS and allow only documented Ark or Volcengine API hostnames. 3. Parse the endpoint with `new URL()` and reject embedded credentials, unexpected ports, fragments, and non-HTTPS schemes. 4. Require a separate explicit flag before allowing a non-default endpoint. 5. Display the exact credential destination and request user confirmation when a custom endpoint is selected. 6. Disable redirects for authenticated requests or strip the `Authorization` header whenever the origin changes. 7. Keep credentials scoped to the minimum provider permissions and billing quota. 8. Add automated tests verifying that credentials are never sent to unapproved origins. 9. Document the security implications of endpoint overrides rather than treating them as ordinary model configuration. ]]>

T08 · Insecure Dependencies

Note
Location
references/provider-cli.md:64
Finding
Documentation Recommends Direct Execution of an Externally Retrieved npm Package<![CDATA[ ## Vulnerability Details **File Location**: `references/provider-cli.md:64-71` **Vulnerability Type**: Third-party package execution and supply-chain exposure **Risk Level**: Low ### Vulnerable Code ```bash npx @dlazy/cli@1.2.3 <command> # 不装全局二进制 ``` ```markdown - CLI 源码:[github.com/dlazy-ai/cli](https://github.com/dlazy-ai/cli) · npm 包 `@dlazy/cli` ``` ### Technical Analysis The documentation recommends using `npx` to retrieve and execute `@dlazy/cli` directly from the npm ecosystem. The package version is explicitly pinned to `1.2.3`, which reduces version drift and is safer than executing an unversioned package. Nevertheless, the package is not included in the audited project, and no integrity hash, vendored source, lockfile, or package-signature verification is provided. The effective code executed by this command therefore lies outside the reviewed artifact. Running `npx` can execute the package's CLI code and potentially npm lifecycle behavior with the invoking user's local permissions. This creates a supply-chain trust boundary. There is no evidence in the reviewed project that the named package is malicious; the risk is that external registry content cannot be verified from this artifact alone. ### Attack Path 1. A user follows the documented command. 2. `npx` retrieves `@dlazy/cli@1.2.3` and its dependency graph from the configured npm registry or cache. 3. npm executes package-controlled code. 4. If the package version, registry account, registry infrastructure, dependency graph, or local npm configuration has been compromised, malicious code runs under the user's account. 5. Such code could access files and environment variables available to the invoking process, including generation-provider credentials. ### Impact Assessment The package runs with the permissions of the user invoking `npx`. A compromised dependency could potentially: - Read user-accessible files. - Read environment variables and API credentials. - Modify f ...[truncated 309 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer the provider implementations included in the audited project when they support the required workflow. 2. If the CLI is required, vendor a reviewed release or provide a lockfile containing verified integrity metadata. 3. Publish and document a cryptographic checksum or signed provenance for the approved package artifact. 4. Instruct users to verify the package source, publisher, version, and integrity before execution. 5. Use an isolated environment or container with only the filesystem and credentials required for generation. 6. Disable unnecessary npm lifecycle scripts where operationally possible. 7. Avoid granting the CLI access to unrelated credentials or sensitive directories. 8. Periodically review the pinned package and its transitive dependencies for newly disclosed vulnerabilities. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (2)

Vague Triggers

Medium
Confidence
95% confidence
Finding
The skill advertises very broad trigger phrases such as '做条广告', '短视频', and '分镜脚本', which can match many ordinary user requests outside this skill’s intended scope. This can cause the agent to invoke the workflow unexpectedly, leading to unintended file-writing, tool execution, and model usage in contexts where the user did not clearly ask for this specific advertising pipeline.

Missing User Warnings

Low
Confidence
86% confidence
Finding
The workflow documentation describes generating clips, subtitles, concat manifests, and final rendered videos under an output directory, but it does not explicitly warn that these files are written to disk and may overwrite prior outputs. In an agent setting, missing this warning can lead to accidental data loss or unexpected persistence of generated media on the local filesystem.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/lib/providers.mjs:104

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/video.mjs:69

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/gen.mjs:118

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/lib/providers.mjs:21