security: Path traversal vulnerability in file upload handler #4

Open
opened 2026-06-17 15:02:39 +00:00 by abumahid · 0 comments
Owner

Description

The multer uploader middleware uses file.originalname directly without sanitization when saving uploaded files. This allows attackers to traverse directories and write files outside the intended upload directory using path traversal payloads (e.g., ../../etc/passwd.txt).

Location

  • File: src/app/middlewares/uploader.ts
  • Component: uploader (multer diskStorage)
  • Lines: 8-11

How to Fix

Replace unsanitized file.originalname with a safe filename. Use uuid or timestamp-based naming:

import multer from "multer";
import path from "path";
import { v4 as uuidv4 } from "uuid";

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, path.join(process.cwd(), "uploads"))
    },
    filename: function (req, file, cb) {
        // Use UUID + original extension instead of original filename
        const ext = path.extname(file.originalname);
        const filename = `${uuidv4()}${ext}`;
        cb(null, filename);
    }
})

const uploader = multer({ storage: storage })

export default uploader;

Acceptance Criteria

  • Filename is generated using UUID or timestamp instead of user input
  • Original filename is not used in file path
  • All file uploads use the new safe naming mechanism
  • Build passes without errors
  • No regression in file upload functionality
### Description The multer uploader middleware uses `file.originalname` directly without sanitization when saving uploaded files. This allows attackers to traverse directories and write files outside the intended upload directory using path traversal payloads (e.g., `../../etc/passwd.txt`). ### Location - **File:** `src/app/middlewares/uploader.ts` - **Component:** `uploader` (multer diskStorage) - **Lines:** 8-11 ### How to Fix Replace unsanitized `file.originalname` with a safe filename. Use uuid or timestamp-based naming: ```typescript import multer from "multer"; import path from "path"; import { v4 as uuidv4 } from "uuid"; const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, path.join(process.cwd(), "uploads")) }, filename: function (req, file, cb) { // Use UUID + original extension instead of original filename const ext = path.extname(file.originalname); const filename = `${uuidv4()}${ext}`; cb(null, filename); } }) const uploader = multer({ storage: storage }) export default uploader; ``` ### Acceptance Criteria - [ ] Filename is generated using UUID or timestamp instead of user input - [ ] Original filename is not used in file path - [ ] All file uploads use the new safe naming mechanism - [ ] Build passes without errors - [ ] No regression in file upload functionality
abumahid added the securityCritical labels 2026-06-17 15:02:39 +00:00
abumahid added this to the quicklanch-server project 2026-06-17 15:02:39 +00:00
Sign in to join this conversation.