Skip to content
This repository was archived by the owner on Mar 13, 2026. It is now read-only.

fix: add path traversal validation and safer file operations#53

Merged
RishabhS7 merged 6 commits intomasterfrom
fix/path-traversal
Oct 17, 2025
Merged

fix: add path traversal validation and safer file operations#53
RishabhS7 merged 6 commits intomasterfrom
fix/path-traversal

Conversation

@rongquan1
Copy link
Copy Markdown

@rongquan1 rongquan1 commented Oct 15, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Strengthened file-path validation to prevent directory traversal and ensure source files exist before processing.
    • Replaced permission-check reliance with a canonical-path validation workflow and clearer error handling.
    • Improved cleanup using a more reliable directory removal method.
  • Refactor

    • Centralized and standardized path handling across setup and monitoring flows.
    • Ensured all file copy and monitoring operations use validated canonical paths.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 15, 2025

Walkthrough

Adds a canonical path validation helper validateFilePath, replaces raw path and permission-check logic with validated canonical paths across monitor and setup flows, switches directory removal to rmSync, and updates imports to use relative, isAbsolute, and rmSync.

Changes

Cohort / File(s) Summary of Changes
Path validation, setup & monitor
performance-tests/wrap-performance-test.ts
Added validateFilePath(filePath, baseDir) to resolve and canonicalize paths and ensure the input lives inside an allowed base directory; monitor now calls this and passes the canonical path into setup; removed inline unsafe traversal and access checks.
Imports & filesystem ops
performance-tests/wrap-performance-test.ts
Updated imports: removed rmdirSync and access, added rmSync, relative, and isAbsolute; replaced rmdirSync usage with rmSync for recursive cleanup; file copy uses canonical source path.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Runner as Test Runner
  participant Wrapper as wrap-performance-test.ts
  participant Validator as validateFilePath
  participant Setup as setup
  participant FS as File System

  Runner->>Wrapper: invoke(filePath)
  Wrapper->>Validator: validateFilePath(filePath, baseDir)
  Validator-->>Wrapper: canonicalPath OR error

  alt valid
    Wrapper->>FS: copyFile(canonicalPath -> inputDir)
    Wrapper->>Setup: setup(canonicalPath)
    Setup-->>Wrapper: ready
    Wrapper->>FS: rmSync(inputDir, { recursive: true })
    Wrapper->>FS: rmSync(outputDir, { recursive: true })
  else invalid
    Wrapper-->>Runner: throw validation error
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I hop through paths, I check each lair,
Canonical tunnels — no tricks in there.
I copy, watch, then tidy with a sweep,
rmSync clears the burrows, safe and neat. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description is entirely missing. The repository requires a structured description following a template with three key sections: Summary (background context), Changes (detailed list of modifications), and Issues (related references). Without any description provided by the author, all required sections are absent, making it impossible to understand the background, rationale, or related context for this security-focused change from the description alone.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "fix: add path traversal validation and safer file operations" directly corresponds to the main changes in the changeset. According to the raw summary, the primary objectives are introducing a validateFilePath helper function to prevent path traversal attacks and replacing unsafe path handling with safer operations (such as using rmSync instead of rmdirSync). The title is concise, specific, and clearly communicates what was fixed without being vague or overly broad.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/path-traversal

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0e2def and 8db55fd.

📒 Files selected for processing (1)
  • performance-tests/wrap-performance-test.ts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests / Run Tests
🔇 Additional comments (5)
performance-tests/wrap-performance-test.ts (5)

4-4: LGTM!

The import additions correctly support the new path validation logic and the migration from rmdirSync to rmSync.

Also applies to: 6-6


14-32: Excellent security implementation!

The validateFilePath helper correctly addresses all previous security concerns:

  • Canonicalizes both file and base directory paths to resolve symlinks
  • Uses relative + boundary checks instead of unsafe startsWith
  • Prevents path traversal and cross-drive escapes
  • Provides clear error messages

The implementation is secure and ready for production use.


35-51: LGTM!

The setup function now correctly receives and uses the pre-validated canonical path. The removal of inline validation and redundant access() checks improves code clarity and eliminates the TOCTOU window previously flagged.


68-72: LGTM!

The input path validation is correctly applied before setup, and the canonical path is properly passed through. The error handling ensures cleanup occurs even if validation fails.


54-58: LGTM

Switching from rmdirSync to rmSync({ recursive: true }) is correct and fully supported by the project’s Node.js 18.x requirement.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e49230 and 5596614.

📒 Files selected for processing (2)
  • performance-tests/wrap-performance-test.ts (5 hunks)
  • tradetrust-cli (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Linters / Code Lint
performance-tests/wrap-performance-test.ts

[failure] 32-32:
Replace '..' with ".."


[failure] 24-24:
Delete ····


[failure] 86-86:
Replace '..' with ".."

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests / Run Tests
🔇 Additional comments (3)
tradetrust-cli (1)

1-1: Submodule update acknowledged.

The submodule pointer has been updated to commit 0e49230bb41cb4b7fc74cec001d4f0677616a548. The referenced commit contains a gas station URL fix that appears reasonable.

performance-tests/wrap-performance-test.ts (2)

64-65: Good modernization of filesystem cleanup.

The switch from rmdirSync to rmSync is appropriate. rmSync is the recommended API for recursive directory removal and provides better error handling.


51-54: Correct usage of validated paths.

The file operations correctly use resolvedFilePath for both access checking and copying. This ensures that the validated path is consistently used throughout the function.

Copy link
Copy Markdown

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
performance-tests/wrap-performance-test.ts (1)

79-82: Remove redundant validation check.

This validation at lines 79-82 is redundant with the more comprehensive validation performed at lines 84-88. The second check includes both the startsWith validation and additional normalization checks.

Apply this diff to remove the redundant check:

-    // Ensure the file path is within the allowed directory
-    if (!absoluteFilePath.startsWith(__dirname)) {
-      throw new Error("Unsafe file path detected.");
-    }
-
♻️ Duplicate comments (2)
performance-tests/wrap-performance-test.ts (2)

22-39: Path validation issues already flagged in previous reviews.

The validation logic here has been identified in previous reviews as having:

  1. Redundant normalization (line 31)
  2. False positive risk with the .includes('..') check (line 32)
  3. Symlink vulnerability with the startsWith(__dirname) approach (line 26)
  4. Linting issues (lines 24, 32)

Please refer to the previous review comments for the recommended realpath-based approach and shared validation helper.


84-88: Duplicate validation logic with issues flagged in previous reviews.

This validation logic duplicates the problematic checks from the setup function (lines 22-39) and has been flagged in previous reviews for:

  1. Redundant normalization
  2. False positive risk with .includes('..') check
  3. Linting issue at line 86 (single quotes)

Please refer to the previous review comments for the recommended refactored approach using a shared validation helper with realpath.

🧹 Nitpick comments (1)
performance-tests/wrap-performance-test.ts (1)

27-27: Improve error message consistency.

The error messages for path validation failures are inconsistent across the file:

  • "Source file path is outside the allowed directory" (line 27)
  • "Path traversal attempt detected in source file path" (line 33)
  • "Unsafe file path detected" (lines 47, 81)
  • "Path traversal attempt detected in input file path" (line 87)

Consider standardizing the error messages and including the actual path value for easier debugging.

Example:

throw new Error(`Path validation failed: "${filePath}" is outside the allowed directory`);

Also applies to: 33-33, 47-47, 81-81, 87-87

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5596614 and 7c594b2.

📒 Files selected for processing (1)
  • performance-tests/wrap-performance-test.ts (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests / Run Tests
🔇 Additional comments (2)
performance-tests/wrap-performance-test.ts (2)

4-4: LGTM: Imports support the new validation and cleanup logic.

The added imports (rmSync, promises, constants, normalize) are correctly used throughout the file for enhanced path validation and safer file operations.

Also applies to: 7-7


64-65: LGTM: Correct migration to rmSync.

The replacement of rmdirSync with rmSync is the proper approach for recursive directory removal in modern Node.js.

@rongquan1 rongquan1 changed the title fix: add path traversal validation and safer file operations in wrap … fix: add path traversal validation and safer file operations Oct 15, 2025
Copy link
Copy Markdown

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
performance-tests/wrap-performance-test.ts (1)

44-47: Fix unsafe output path validation.

The startsWith check on line 45 has the same prefix-matching vulnerability as the helper function. If INPUT_UNWRAPPED_FILE_FOLDER is /home/user/setup/raw-documents, a path like /home/user/setup/raw-documents-backup/file.json would incorrectly pass validation.

Apply this diff to fix the output path validation:

-    // Sanitize the file path to prevent directory traversal
-    if (!outputPath.startsWith(INPUT_UNWRAPPED_FILE_FOLDER)) {
-      throw new Error("Unsafe file path detected.");
-    }
+    // Sanitize the file path to prevent directory traversal
+    const { relative, isAbsolute } = require("path");
+    const relativeOutputPath = relative(INPUT_UNWRAPPED_FILE_FOLDER, outputPath);
+    if (relativeOutputPath.startsWith("..") || isAbsolute(relativeOutputPath)) {
+      throw new Error("Unsafe file path detected.");
+    }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c594b2 and 4c19360.

📒 Files selected for processing (1)
  • performance-tests/wrap-performance-test.ts (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests / Run Tests
🔇 Additional comments (2)
performance-tests/wrap-performance-test.ts (2)

36-50: Good use of the validation helper.

The canonical path is properly obtained and propagated from monitorWrapFeature to setup, and the validated path is used for file operations. Once the helper function's validation logic is fixed, this usage will be secure.

Also applies to: 72-76


58-62: LGTM: Proper use of rmSync.

Correctly replaced the deprecated rmdirSync with rmSync. The recursive: true option is appropriate for directory removal.

Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (1)
performance-tests/wrap-performance-test.ts (1)

46-51: Consider using relative() for consistency.

The safety check on line 49 uses startsWith(), which could theoretically have false positives when directory names share a prefix. While unlikely given how outputPath is constructed, using the same relative() approach as validateFilePath would be more consistent and robust.

Optional refactor:

     const outputPath = resolve(INPUT_UNWRAPPED_FILE_FOLDER, `${fileName + (index + 1)}${fileExtension}`);

     // Sanitize the file path to prevent directory traversal
-    if (!outputPath.startsWith(INPUT_UNWRAPPED_FILE_FOLDER)) {
+    const relPath = relative(INPUT_UNWRAPPED_FILE_FOLDER, outputPath);
+    if (relPath.startsWith("..") || isAbsolute(relPath)) {
       throw new Error("Unsafe file path detected.");
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c19360 and d0e2def.

📒 Files selected for processing (1)
  • performance-tests/wrap-performance-test.ts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests / Run Tests
🔇 Additional comments (3)
performance-tests/wrap-performance-test.ts (3)

14-32: LGTM! Path validation is now secure.

The validateFilePath helper correctly addresses the security concerns raised in previous reviews:

  1. ✅ Base directory is canonicalized (line 23) to handle symlinks
  2. ✅ Uses relative() instead of startsWith() to prevent false positives
  3. ✅ Checks for ".." prefix to detect parent directory escapes
  4. ✅ Checks for absolute paths to catch different drive/root scenarios (Windows)

This implementation properly defends against symlink attacks and directory traversal.


64-65: LGTM! Using modern rmSync API.

Correctly replaces the deprecated rmdirSync with rmSync for recursive directory removal.


76-80: LGTM! Input validation properly integrated.

The monitor flow correctly validates the input file path and passes the canonical path to setup, ensuring consistent security checks throughout the codebase.

@rongquan1 rongquan1 requested a review from RishabhS7 October 17, 2025 05:31
@RishabhS7 RishabhS7 merged commit fb30d0a into master Oct 17, 2025
10 checks passed
@RishabhS7 RishabhS7 deleted the fix/path-traversal branch October 17, 2025 05:43
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 3.2.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants