Skip to content
Open
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
**Vulnerability:** Raw error objects from FFmpeg and browser APIs (`error.message` and `console.error`) were being rendered directly in the user interface and browser console.
**Learning:** Returning unhandled exception messages to the client risks exposing internal stack traces, system paths, and unexpected framework vulnerabilities to potential attackers.
**Prevention:** Catch error blocks should log a sanitized version of the error or omit sensitive details, while the state presented to the user should be a generic, friendly, and secure fallback message (e.g. "Processing failed securely").

## 2024-05-18 - Path Traversal in File Uploads
**Vulnerability:** Unsanitized user-provided filenames (e.g. `file.name`) in `FormData` can include directory traversal sequences (like `../`), potentially allowing arbitrary file writes outside the intended server directory.
**Learning:** The `crypto.randomUUID()` prefix alone does not protect against path traversal if the malicious input contains `../` sequences that escape the directory hierarchy.
**Prevention:** Always sanitize uploaded filenames using `path.basename()` before concatenating them into server-side file paths.
5 changes: 4 additions & 1 deletion src/app/api/video/[tool]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ export async function POST(

const tmpDir = `/tmp/omni/video`;
await fs.mkdir(tmpDir, { recursive: true });
const inputPath = `${tmpDir}/${crypto.randomUUID()}_${file.name}`;

// Sanitize user-provided filename to prevent Path Traversal vulnerabilities
const safeFileName = file.name ? path.basename(file.name) : 'unnamed_file';
const inputPath = path.join(tmpDir, `${crypto.randomUUID()}_${safeFileName}`);

// Write file to disk
const arrayBuffer = await file.arrayBuffer();
Expand Down
Loading