Skip to content

[Bug] dashboard-api: uploadFile does not sanitize file.originalname before use in storage path, allowing path injection characters #261

Description

@anshul23102

Describe the bug

In apps/public-api/src/controllers/storage.controller.js, the uploaded file's original filename is used directly in the Supabase storage path after only replacing spaces:

const safeName = file.originalname.replace(/\s+/g, "_");
const filePath = `${project._id}/${randomUUID()}_${safeName}`;

The originalname field comes from the HTTP multipart upload and is entirely user-controlled. Characters such as ../, null bytes (%00), or Unicode directory separators are not stripped. While the random UUID prefix reduces the practical risk of path traversal, the unsanitized filename is sent verbatim to Supabase's storage API and is also returned to the client in the path response field.

A crafted filename like ../../secret.pdf or valid.pdf\x00.jpg may exploit permissive storage backends or confuse downstream filename parsers that use the stored path.

To Reproduce

  1. Send a POST /api/storage/upload request with Content-Type: audio/webm and set the filename in the multipart header to ../../test.webm.
  2. Observe that the path field in the response contains the unsanitized string (e.g., projectId/uuid_../../test.webm).

Expected behavior

The filename should be sanitized to safe characters before use in any path construction:

const safeName = file.originalname
    .replace(/[^a-zA-Z0-9._-]/g, "_")
    .replace(/\.{2,}/g, "_")
    .substring(0, 100);
const filePath = `${project._id}/${randomUUID()}_${safeName}`;

Additional context

File: apps/public-api/src/controllers/storage.controller.js, function: uploadFile

Labels: bug, nsoc26, level2

Checklist:

  • Searched existing issues - not a duplicate
  • Read CONTRIBUTING.md
  • No AI/Claude mentions
  • No em dashes or double hyphens
  • Repository verified as NSOC

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions