Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions assistant/src/daemon/handlers/recording.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as net from 'node:net';
import { existsSync, statSync } from 'node:fs';
import { existsSync, realpathSync, statSync } from 'node:fs';
import * as path from 'node:path';
import { v4 as uuid } from 'uuid';
import type { RecordingStatus, RecordingOptions } from '../ipc-protocol.js';
Expand Down Expand Up @@ -202,13 +202,26 @@ function handleRecordingStatus(
if (msg.filePath) {
// Restrict accepted file paths to the app's recordings directory to
// prevent attachment of arbitrary files via crafted IPC messages.
const resolvedPath = path.resolve(msg.filePath);
let resolvedPath: string;
try {
resolvedPath = realpathSync(msg.filePath);
} catch {
// File doesn't exist (broken symlink or missing) — use path.resolve
// as fallback; the existsSync check below will handle the missing file.
resolvedPath = path.resolve(msg.filePath);
}
const allowedDir = path.join(
process.env.HOME ?? '',
'Library/Application Support/vellum-assistant/recordings',
Comment thread
Jasonnnz marked this conversation as resolved.
);
if (!resolvedPath.startsWith(allowedDir + path.sep) && resolvedPath !== allowedDir) {
log.warn({ recordingId, filePath: msg.filePath, allowedDir }, 'Recording file path outside allowed directory — rejecting');
let resolvedAllowedDir: string;
try {
resolvedAllowedDir = realpathSync(allowedDir);
} catch {
resolvedAllowedDir = allowedDir;
}
if (!resolvedPath.startsWith(resolvedAllowedDir + path.sep) && resolvedPath !== resolvedAllowedDir) {
log.warn({ recordingId, filePath: msg.filePath, allowedDir, resolvedAllowedDir }, 'Recording file path outside allowed directory — rejecting');
if (notifySocket) {
ctx.send(notifySocket, {
type: 'assistant_text_delta',
Expand Down