diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 2ceab100..7ed35fa0 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -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. diff --git a/src/app/api/video/[tool]/route.ts b/src/app/api/video/[tool]/route.ts index a7307430..c6cf1257 100644 --- a/src/app/api/video/[tool]/route.ts +++ b/src/app/api/video/[tool]/route.ts @@ -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();