T09 · Insecure Skill Coding Practices
- 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: HighVulnerable 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.artifactsfrom the configured remote rendering service. For each artifact, it uses the remoteartifact.namedirectly in:js const target = join(outDir, artifact.name); writeFileSync(target, buffer);join()normalizes traversal components but does not enforce containment withinoutDir. For example, an artifact name such as../../target-fileresolves 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
verifiedfield tofalse; it does not prevent or undo the write.Attack Path
- The user configures the client to use an attacker-controlled or compromised compatible rendering service through
--api-baseorSRV_API_BASE. - The user completes the documented probe and payment-proof workflow.
- The service returns a successful response with `Payment-Vali ...[truncated 1316 chars]
- The user configures the client to use an attacker-controlled or compromised compatible rendering service through
- 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, andaudit_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.
