Back to skill

Security audit

Second Reality Video · Open Client

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for a paid video-rendering client, but it needs review because a render service can cause local file writes outside the chosen output folder and the payment setup uses an unpinned remote install command.

Review before installing or using against a real service. Use the bundled mock service or a sandbox first, avoid untrusted render endpoints, pin and verify any payment-capability installer, and only run real payments after the client rejects unsafe artifact names and fails closed on digest mismatches.

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/second-reality-video-client.mjs:278
Finding

Remote Artifact Name Allows Arbitrary File Overwrite via Path Traversal

Content
View full analysis

Vulnerability Details

File Location: scripts/second-reality-video-client.mjs, lines 278–291
Vulnerability Type: Path traversal leading to arbitrary file overwrite
Risk Level: High

Vulnerable code:

js
const downloaded = [];
for (const artifact of artifacts) {
  const target = join(outDir, artifact.name);
  const res = await fetch(`${state.api_base}${artifact.url}`);
  if (!res.ok) {
    console.error(`产物下载失败:${artifact.name} HTTP ${res.status}`);
    return EXIT_ERROR;
  }
  const buffer = Buffer.from(await res.arrayBuffer());
  writeFileSync(target, buffer);
  const digest = createHash('sha256').update(buffer).digest('hex');
  downloaded.push({
    name: artifact.name,
    path: target,

Technical Analysis

The client obtains content.artifacts from the configured remote rendering service. For each artifact, it uses the remote artifact.name directly in:

js
const target = join(outDir, artifact.name);
writeFileSync(target, buffer);

join() normalizes traversal components but does not enforce containment within outDir. For example, an artifact name such as ../../target-file resolves outside the selected output directory. Absolute-path behavior and platform-specific separators also require explicit rejection.

The client checks whether the HTTP download succeeds but performs no filename allowlisting, path-containment validation, or symbolic-link-safe file creation before writing. The computed SHA-256 digest is recorded only after the write. Moreover, a digest mismatch merely sets the reported verified field to false; it does not prevent or undo the write.

Attack Path

  1. The user configures the client to use an attacker-controlled or compromised compatible rendering service through --api-base or SRV_API_BASE.
  2. The user completes the documented probe and payment-proof workflow.
  3. The service returns a successful response with `Payment-Vali ...[truncated 1316 chars]
Remediation
View remediation

Remediation Suggestions

  • Treat every artifact name and URL returned by the service as untrusted.
  • Prefer a strict allowlist of expected artifact filenames, such as world.mp4, hashes.txt, frames.jsonl, identity_assets.json, manifest.json, and audit_report.txt.
  • Reject empty names, absolute paths, . or .. components, path separators, NUL characters, and platform-specific path syntax.
  • Resolve the destination and verify containment before writing:
    js
    import { basename, relative, resolve, sep } from 'node:path';
    
    const safeName = basename(String(artifact.name));
    if (safeName !== artifact.name || safeName === '.' || safeName === '..') {
      throw new Error('Invalid artifact name');
    }
    
    const target = resolve(outDir, safeName);
    const rel = relative(outDir, target);
    if (rel === '..' || rel.startsWith(`..${sep}`) || rel === '' && target === outDir) {
      throw new Error('Artifact path escapes output directory');
    }
    
  • Defend against pre-existing symbolic links by opening files with exclusive and no-follow semantics where supported, or write into a newly created private directory and verify each path component.
  • Download into a safe temporary file inside the output directory, verify the declared digest before publication, and atomically rename it only after successful validation.
  • Reject the delivery entirely when an advertised SHA-256 digest is present but does not match.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · PACKING.md (reported line 26)May include surrounding context.

text
.state/        # session state: bill + original request (contains order data)
node_modules/  # installed dependencies
.env / .env.*  # environment files
out/           # downloaded artifacts
*.log          # runtime logs
__pycache__/   # bytecode

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| ✅ Included | `scripts/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| ✅ Included | `scripts/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| ✅ Included | `scripts/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| ✅ Included | `scripts/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| ✅ Included | `scripts/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| ✅ Included | `scripts/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator), API contract, shot-f

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator), API contract, shot-f

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
/second-reality-video-client.mjs` (probe / pay / complete / status / pricing), `scripts/mock-service.mjs` (offline 402 protocol simulator), API contract, shot-f

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The README instructs users to execute an unpinned package via npx -y @alipay/agent-payment@latest install, which fetches and runs whatever code is current on the registry at execution time. If the package is compromised, typosquatted, or a malicious version is later published, users could execute attacker-controlled code in their environment, and the payment-related context increases sensitivity because it may expose credentials or facilitate fraudulent actions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The documentation instructs users to execute an unpinned package directly from the registry via npx, which allows whatever code is currently published under that package name to run on the user's machine. If the package is compromised, typo-squatted, or a malicious version is later published, this skill can become a delivery path for arbitrary code execution during payment-capability installation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file contains user-facing protocol documentation exclusively in Chinese, and there is no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific audience. Under the policy, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script downloads server-declared artifacts and writes them to disk before enforcing integrity, and even when a SHA-256 is provided it merely records whether verification passed instead of failing the operation. In this payment-backed client context, that means a compromised or malicious server, manifest, or transport path could deliver tampered files that users may trust as successfully delivered paid content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The README describes using a real service for payment and writing outputs to ./out without an explicit warning that these actions may incur real charges and create or overwrite local files. While this is primarily a safety and UX issue rather than a code exploit, it can still lead to unintended financial cost or filesystem side effects when users follow the instructions verbatim.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

Natural-language strings throughout the script, including usage, errors, and operational guidance, are only presented in Chinese. This imposes a single language/locale on all users without offering a choice or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file is second-reality-video-client.mjs, but the help output says node scripts/second-reality-video-paid.mjs. This inline usage documentation contradicts the actual file identity and can mislead operators about what command they are running.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.