Back to skill

Security audit

主图 A/B 与复盘 Listing Optimizer

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly fits image A/B testing, but it has under-scoped generation backends that can expose private images, prompts, or credentials if configured unsafely.

Review this skill before installing in environments with private product assets or valuable provider keys. Prefer pinned/local tooling, use explicit approved providers, avoid arbitrary image URLs, do not set custom provider base URLs unless they are trusted, and rotate any Ark key that may have been used with an untrusted ARK_BASE_URL.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib/providers.mjs:290
Finding
Ark API Credentials and Private Image Data Can Be Sent to an Arbitrary Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/providers.mjs`, lines 290-301 **Vulnerability Type**: Unvalidated provider endpoint override resulting in sensitive-data disclosure **Risk Level**: High ### Vulnerable Code ```js 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 accepts `ARK_BASE_URL` directly from the process environment and uses it as the destination for an authenticated HTTP request. The value is not restricted to the official Ark hostname and is not required to use HTTPS. The resulting request contains: - The reusable `ARK_API_KEY` bearer credential in the `Authorization` header. - The user's generation prompt. - Generation parameters. - Local reference images encoded as data URIs when images are supplied. Consequently, any party capable of influencing the process environment can redirect the complete authenticated request to an attacker-controlled endpoint. Allowing an `http://` endpoint also permits plaintext transmission and network interception. Cloud transmission itself is necessary for the declared image-generation functionality and is disclosed in the provider documentation. However, sending credentials and private assets to an unrestricted endpoint exceeds the minimum privilege needed to communicate with the legitimate Ark service. ## ...[truncated 1357 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `ARK_BASE_URL` overriding if custom Ark-compatible endpoints are not an explicit requirement. 2. If endpoint overriding is required, parse the value with `new URL()` and enforce: - The `https:` protocol. - An exact allowlist of trusted hostnames. - Approved ports only. - No embedded username or password. - An expected pathname prefix. 3. Do not send `ARK_API_KEY` to a non-official origin. Use separate, endpoint-specific credentials for explicitly supported custom providers. 4. Disable automatic redirects for authenticated requests, or validate every redirect destination before forwarding authorization headers. 5. Require explicit provider selection and informed confirmation before transmitting reference images to a custom endpoint. 6. Document the destination hostname in dry-run output and clearly warn when any non-default endpoint is configured. 7. Add automated tests confirming that HTTP URLs, unapproved domains, embedded credentials, unexpected ports, and cross-origin redirects are rejected. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/lib/providers.mjs:110
Finding
Unpinned Global Installation Recommendation Creates a Third-Party Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/providers.mjs`, lines 110-114 **Vulnerability Type**: Unpinned third-party package installation guidance **Risk Level**: Medium ### Vulnerable Code ```js reject(new Error( e.code === 'ENOENT' ? `找不到 dlazy 命令。装它:npm i -g @dlazy/cli —— 或换后端:PROVIDER=openai|gemini|fal|replicate|ark` : e.message)) ``` The provider documentation separately offers a pinned invocation: ```bash npx @dlazy/cli@1.2.3 <command> ``` However, the runtime error presented to users recommends the unpinned command: ```bash npm i -g @dlazy/cli ``` ### Technical Analysis When the default `dlazy` executable is unavailable, the Skill instructs the user to install the latest version of `@dlazy/cli` globally. No exact version, lockfile, package-integrity value, or verified artifact is specified in this recommendation. npm packages can run lifecycle scripts during installation and subsequently execute with the invoking user's permissions. An unpinned global installation therefore allows the installed code to change after the Skill has been audited. This creates exposure to a compromised publisher account, malicious future release, registry compromise, or other upstream supply-chain failure. The project documentation demonstrates that a pinned version is available, making the unpinned global recommendation unnecessary. ### Attack Path 1. The user invokes the generator without the `dlazy` executable installed. 2. The process fails with `ENOENT` and displays the global-install recommendation. 3. The user runs `npm i -g @dlazy/cli`. 4. npm resolves the package version available at installation time rather than an audited fixed version. 5. If that resolved release or its dependency graph has been compromised, package lifecycle or runtime code executes with the user's permissions. 6. The malicious dependency could access files, environment variables, provider credentials, or network resources available to that user. T ...[truncated 785 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the unpinned recommendation with the audited pinned version already shown in the documentation, for example: ```bash npx --yes @dlazy/cli@1.2.3 ``` 2. Avoid recommending global installation. Prefer a project-local dependency with a committed lockfile. 3. Record and verify npm integrity metadata for the approved package and transitive dependency graph. 4. Use a trusted, explicitly configured registry and document the expected package publisher and source repository. 5. Review new versions before changing the pinned version. 6. Consider disabling lifecycle scripts during installation where compatible: ```bash npm install --ignore-scripts ``` 7. Ensure installation is performed without elevated privileges and in a constrained environment. 8. Make the runtime error consistent with `references/provider-cli.md` so users are not directed away from the safer pinned workflow. ]]>
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose is A/B image testing and retrospective analysis, but the content also invokes a separate compliance-checking capability and suggests automatic remediation behavior not clearly reflected in the metadata. Description-behavior mismatch is dangerous because reviewers and users may authorize the skill for a narrow purpose while it performs broader file-processing and platform-rule operations.

Ae1

High
Category
analysis-evasion
Content
node scripts/gen.mjs --task listing-optimizer --brand examples/brand.yaml \
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/gen.mjs --task listing-optimizer --brand examples/brand.yaml \
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill references command-line generation and compliance-check workflows with implied network and environment access, but it does not declare any tool scope or permissions boundaries. This creates unnecessary ambiguity about what resources the skill may access and increases the chance of over-privileged execution in an agent runtime.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The description says the skill should be used when the user says phrases like “提点击率”, “哪版更好”, and “换个版本试试”. These are common, high-level expressions that could appear in many general ecommerce or creative discussions, and the file does not provide exclusion conditions or tighter trigger scope.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The skill content and invocation guidance are entirely written in Chinese, with no indication that users may choose another language or locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is explicitly justified.

Skill Enumeration

Medium
Category
Agent Snooping
Content
| --- | --- |
| 单变量对照组 | 一次只改一个维度,其余保持一致 |
| 假设记录 | 每组附「预期效果 + 理由」,跑完能复盘 |
| 合规校验 | 每张自动过 [platform-compliance](https://github.com/dlazy-ai/ecommerce-skills/blob/main/skills/platform-compliance/skill.md),避免因驳回污染数据 |
| 复盘模板 | 产出可填数据的对照表 |

| 不能做 | 说明 |
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
- **一次一个变量,一轮两周**。急着一周出结论通常是自欺。
- **先测大变量**。有没有模特、白底还是场景,这类差异远大于色温微调。
- **赢的那版存进 [brand-kit](https://github.com/dlazy-ai/ecommerce-skills/blob/main/skills/brand-kit/skill.md)**,让它成为之后的默认,实验成果才会沉淀。
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The configuration hard-codes a model as an 'East Asian woman' with fixed age-range and body traits, which bakes sensitive demographic constraints into a shared brand file used across many image-generation skills. In this context, that can systematically exclude alternatives, create biased outputs by default, and expose the organization to fairness, discrimination, or marketplace-policy issues when the demographic choice is not user-driven or explicitly justified.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This markdown file contains all user-facing guidance in Chinese, and there is no indication that the skill is region-specific or that users can opt into another language. Under the policy rule for natural-language violations, forcing a specific language without user choice is a reportable issue.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The natural-language comments, docstring, CLI description, and help text are written entirely in Chinese, with no indication that another language is available or that Chinese is a required locale. Under the stated policy, forcing a specific language without user opt-in is a locale-policy issue unless the constraint is explicitly documented and justified.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The manifest describes a skill for generating multiple hero-image variants, difference hypotheses, and review templates for A/B testing and CTR optimization. This file instead implements pre-listing compliance validation against marketplace rules and can automatically rewrite images to satisfy those rules, which is a materially different operational purpose from experimentation-oriented listing optimization.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest frames the skill as producing image variants and analysis artifacts for A/B testing, but this code performs concrete file transformation and saves rewritten outputs to disk as compliance-fixed images. Persistently modifying user assets is a stronger behavior than the manifest’s stated optimization/review workflow and is not presented as part of the skill’s declared purpose.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The manifest describes a focused skill that takes product images and selling points to produce multiple comparison-ready main-image variants, hypotheses, and review templates. This script is a generic multi-provider generation entrypoint for many tasks, selected by arbitrary `--task` from `tasks.json`, with support for text/video/image generation and provider/model overrides, which is materially broader than the stated listing-optimizer function.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The manifest is about generating alternative product main images and associated testing hypotheses, but the script explicitly treats some tasks as video skills and requires a video model when configured that way. Supporting video generation is not an obvious or necessary implementation detail for a listing-main-image optimizer.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Natural-language strings throughout the file, including comments and runtime error messages, force a specific language/locale. Under the stated policy, locale-specific language is only acceptable when users are given a choice or the constraint is clearly documented and justified.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest describes a focused skill for generating multiple contrasting product main-image variants, hypotheses, and a review template for A/B conversion analysis. This file instead provides a generic cross-provider generation router supporting multiple vendors, arbitrary prompts, image editing, text outputs, and even video-related request/response handling, which is materially broader than the declared optimization use case.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The interface documentation explicitly includes a `video:boolean` request flag and `run()` may return video URLs, and downstream providers preserve video extensions such as `.mp4`. Video generation is not an obvious requirement for a skill described as creating A/B test product main images and review artifacts for click-through optimization.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The code accepts arbitrary remote image URLs and fetches them server-side, which can enable SSRF against internal services or metadata endpoints if untrusted users control req.images. It also forwards local files and fetched content to third-party providers without any in-file consent, validation, or allowlisting, creating real data-exfiltration and privacy risk in a skill that may process proprietary product assets.

External Transmission

Medium
Category
Data Exfiltration
Content
model: () => env.GEN_MODEL_OPENAI || 'gpt-image-1',
  describe(req) {
    const ep = req.images?.length ? 'images/edits' : 'images/generations'
    return `POST https://api.openai.com/v1/${ep}  model=${openai.model()} size=${mapSize(req.size)} n=${req.batch}`
  },
  async run(req) {
    const key = env.OPENAI_API_KEY
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
: await readFile(p)
        fd.append('image[]', new Blob([buf], { type: mimeOf(p) }), path.basename(p))
      }
      r = await fetch('https://api.openai.com/v1/images/edits', {
        method: 'POST', headers: { authorization: `Bearer ${key}` }, body: fd,
      })
    } else {
Confidence
95% confidence
Finding
This request uploads user-provided images to OpenAI’s edits endpoint, which is an external data transfer of potentially sensitive business assets. In this skill context, sending product images off-platform may be expected, but without strong disclosure, provider restrictions, and data-handling controls it creates confidentiality and compliance risk.

External Transmission

Medium
Category
Data Exfiltration
Content
: await readFile(p)
        fd.append('image[]', new Blob([buf], { type: mimeOf(p) }), path.basename(p))
      }
      r = await fetch('https://api.openai.com/v1/images/edits', {
        method: 'POST', headers: { authorization: `Bearer ${key}` }, body: fd,
      })
    } else {
Confidence
95% confidence
Finding
This request uploads user-provided images to OpenAI’s edits endpoint, which is an external data transfer of potentially sensitive business assets. In this skill context, sending product images off-platform may be expected, but without strong disclosure, provider restrictions, and data-handling controls it creates confidentiality and compliance risk.

External Transmission

Medium
Category
Data Exfiltration
Content
method: 'POST', headers: { authorization: `Bearer ${key}` }, body: fd,
      })
    } else {
      r = await fetch('https://api.openai.com/v1/images/generations', {
        method: 'POST',
        headers: { authorization: `Bearer ${key}`, 'content-type': 'application/json' },
        body: JSON.stringify({
Confidence
86% confidence
Finding
This call sends prompts and generation parameters to OpenAI’s external API. The risk is lower than file upload, but prompts can still contain sensitive campaign, product, or strategy information; the transmission is therefore a real privacy/compliance concern rather than a code-execution flaw.

External Transmission

Medium
Category
Data Exfiltration
Content
method: 'POST', headers: { authorization: `Bearer ${key}` }, body: fd,
      })
    } else {
      r = await fetch('https://api.openai.com/v1/images/generations', {
        method: 'POST',
        headers: { authorization: `Bearer ${key}`, 'content-type': 'application/json' },
        body: JSON.stringify({
Confidence
86% confidence
Finding
This call sends prompts and generation parameters to OpenAI’s external API. The risk is lower than file upload, but prompts can still contain sensitive campaign, product, or strategy information; the transmission is therefore a real privacy/compliance concern rather than a code-execution flaw.

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

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