Skip to content

Potential fix for code scanning alert no. 184: Type confusion through parameter tampering#205

Open
perinst wants to merge 1 commit intofeature/mergefrom
fix/alert-security-184
Open

Potential fix for code scanning alert no. 184: Type confusion through parameter tampering#205
perinst wants to merge 1 commit intofeature/mergefrom
fix/alert-security-184

Conversation

@perinst
Copy link
Collaborator

@perinst perinst commented Aug 30, 2025

Potential fix for https://github.com/perinst/dozu-api-service/security/code-scanning/184

The correct fix is to perform a runtime type check on files immediately after assignment from req.files in the controller (uploadMultipleFiles). Specifically, before using any array operations (like .length or for ... of), ensure that files is an array and not a string or other unexpected type. If the check fails, throw a BadRequest error.

Change the following in src/controllers/uploads/upload.file.controller.ts:

  • In uploadMultipleFiles, after assigning const files = req.files as Express.Multer.File[];, check that files is an array using Array.isArray(files).
  • If not, throw a BadRequest with a message like 'Malformed files parameter'.
  • Optionally, narrow the cast (remove as Express.Multer.File[] from the assignment; cast after the check for type safety).

This ensures the downstream code (processMultipleFiles) receives a real array only, preventing type confusion and abuse.

No changes are required in the service; the controller will now guarantee the type for the service.


Suggested fixes powered by Copilot Autofix. Review carefully before merging.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced upload handling with stricter validation to ensure at least one valid file is provided before processing.
    • Displays a clearer error message when no files are uploaded or when the upload payload is malformed, replacing ambiguous failures.
    • Improves reliability and user guidance for multi-file submissions by preventing invalid requests from proceeding.

… parameter tampering

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 30, 2025

Walkthrough

Adds runtime validation for req.files, ensuring it is a non-empty array before processing. On invalid input, throws a BadRequest with a specific message. The service call now casts at the call site while leaving other logic unchanged.

Changes

Cohort / File(s) Summary
Upload controller validation update
src/controllers/uploads/upload.file.controller.ts
Replaced unconditional type assertion of req.files with Array.isArray and non-empty check; throws BadRequest on invalid. Adjusted service call to cast at call site. No changes to exported/public signatures.

Sequence Diagram(s)

sequenceDiagram
  participant C as Client
  participant UC as UploadFileController
  participant S as UploadFileService

  C->>UC: POST /uploads (multipart files)
  UC->>UC: Validate req.files is non-empty array
  alt Invalid files
    UC-->>C: 400 BadRequest ("No files uploaded or malformed files parameter")
  else Valid files
    UC->>S: processMultipleFiles(files as Express.Multer.File[])
    S-->>UC: Result
    UC-->>C: 200 OK (result)
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I nibbled the bytes with careful delight,
Checked every file in the basket just right.
If empty, I thump—“Bad request tonight!”
When valid, I hop to the service in flight—
Carrots compiled, uploads alight. 🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/alert-security-184

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@perinst perinst marked this pull request as ready for review August 30, 2025 15:10
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/controllers/uploads/upload.file.controller.ts (2)

103-117: Make cleanup resilient to memoryStorage (no path).

fs.existsSync(undefined) throws; you catch it, but it spams logs. Guard path presence first.

-                req.files.forEach((file: Express.Multer.File) => {
+                req.files.forEach((file: Express.Multer.File) => {
                     try {
-                        if (fs.existsSync(file.path)) {
+                        if (typeof (file as any).path === 'string' && fs.existsSync((file as any).path)) {
-                            fs.unlinkSync(file.path);
+                            fs.unlinkSync((file as any).path);
                         }
                     } catch (cleanupError) {

1-1: Use a type-only import for Express to avoid emitting a runtime import.

Small TS hygiene improvement.

-import { Express } from 'express';
+import type { Express } from 'express';
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 52ac80a and 6d08463.

📒 Files selected for processing (1)
  • src/controllers/uploads/upload.file.controller.ts (1 hunks)
🔇 Additional comments (1)
src/controllers/uploads/upload.file.controller.ts (1)

88-95: Ignore this comment – the middleware already uses multer.array, so req.files is guaranteed to be an array.

Likely an incorrect or invalid review comment.

Comment on lines +88 to 91
const files = req.files;
if (!Array.isArray(files) || files.length === 0) {
throw new BadRequest('No files uploaded or malformed files parameter');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Harden req.files validation with a proper type guard (array + element shape).

Array-only check still permits type confusion via arrays of non-file objects. Validate each element has expected Multer fields, then narrow to Express.Multer.File[].

Apply within this hunk:

-            const files = req.files;
-            if (!Array.isArray(files) || files.length === 0) {
-                throw new BadRequest('No files uploaded or malformed files parameter');
-            }
+            const files = req.files;
+            if (!isMulterFileArray(files) || files.length === 0) {
+                throw new BadRequest('No files uploaded or malformed files parameter');
+            }

Add these type guards near the top of the file (after imports):

// Runtime type guards for Multer file(s)
const isMulterLikeFile = (f: unknown): f is Express.Multer.File =>
  !!f &&
  typeof f === 'object' &&
  'originalname' in (f as any) &&
  'mimetype' in (f as any) &&
  ('path' in (f as any) || 'buffer' in (f as any));

const isMulterFileArray = (x: unknown): x is Express.Multer.File[] =>
  Array.isArray(x) && x.every(isMulterLikeFile);
🤖 Prompt for AI Agents
In src/controllers/uploads/upload.file.controller.ts around lines 88 to 91, the
current check only verifies req.files is an array but allows non-file objects;
add runtime type guards after imports: isMulterLikeFile (checks object,
originalname, mimetype and path or buffer) and isMulterFileArray (Array.isArray
+ every(isMulterLikeFile)), then replace the existing Array.isArray(files) check
with isMulterFileArray(req.files), throwing BadRequest if it fails and narrowing
files to Express.Multer.File[] when it passes so downstream code has the correct
type.


// Process the uploaded files
const result = await uploadFileService.processMultipleFiles(files);
const result = await uploadFileService.processMultipleFiles(files as Express.Multer.File[]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid unsafe type assertion; rely on narrowed type.

Once narrowed with a type guard, you can pass files without casting.

-            const result = await uploadFileService.processMultipleFiles(files as Express.Multer.File[]);
+            const result = await uploadFileService.processMultipleFiles(files);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const result = await uploadFileService.processMultipleFiles(files as Express.Multer.File[]);
const result = await uploadFileService.processMultipleFiles(files);
🤖 Prompt for AI Agents
In src/controllers/uploads/upload.file.controller.ts around line 94, the call
currently uses an unsafe type assertion "files as Express.Multer.File[]";
instead narrow the files variable with a proper type guard or refined check
before calling uploadFileService.processMultipleFiles so you can pass files
directly without casting. Add or use a predicate like isMulterFileArray(files):
files is Express.Multer.File[] (or refine the existing conditional that ensures
files is an array of Multer.File), and then call processMultipleFiles(files)
using the narrowed type.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 6, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant