Skip to content

Conversation

batazor
Copy link
Collaborator

@batazor batazor commented Sep 27, 2025

Summary

Introduces pkg/fsroot to leverage Go 1.25's os.Root for secure filesystem operations, preventing path traversal vulnerabilities. Existing file and directory operations across the codebase have been migrated to use this new SafeFS utility.

Details

This PR implements the os.Root type to restrict filesystem operations to specific directories, enhancing security by preventing path traversal attacks.

Key Changes:

  1. New pkg/fsroot Package:

    • fsroot.go: Defines SafeFS, a wrapper around os.Root, providing secure methods for ReadFile, ReadDir, Create, Open, Remove, Stat, and WriteFile.
    • fsroot_test.go: Comprehensive unit tests for SafeFS functionality.
    • example_test.go: Demonstrates basic usage and security features of SafeFS.
    • README.md: Detailed documentation, API reference, and best practices for fsroot.
  2. Migration to SafeFS:

    • poc/cel/rules.go: loadRules now uses SafeFS to safely read rule files from a designated directory.
    • Protoc Test Files (pkg/protoc/protoc-gen-rich-model/rich_model_test.go, pkg/protoc/protoc-gen-go-orm/ram_orm_test.go, postgres_orm_test.go, mongo_orm_test.go): Updated to use SafeFS for securely reading generated output files within their respective output directories.
    • pkg/s3/s3_test.go: File operations for test fixtures (reading and removing) now utilize SafeFS.
    • boundaries/link/internal/infrastructure/repository/crud/sqlite/sqlite_test.go: The removal of SQLite database files is now handled securely by SafeFS.

This change ensures that all updated filesystem interactions are confined to their intended directories, significantly reducing the risk of unauthorized file access.


Open in Cursor Open in Web

Summary by Sourcery

Leverage Go 1.25 os.Root by introducing SafeFS to restrict filesystem interactions to designated directories and update existing code and tests to use this secure interface.

New Features:

  • Introduce pkg/fsroot with SafeFS wrapper around os.Root for confined filesystem operations

Enhancements:

  • Migrate file and directory operations in CEL rule loader, S3 tests, ORM generator tests, and SQLite cleanup to use SafeFS to prevent path traversal

Documentation:

  • Add README.md in pkg/fsroot with API reference and usage guidelines

Tests:

  • Add fsroot_test.go and example_test.go to validate SafeFS functionality

This change replaces direct file system operations with the SafeFS utility in various test files. This enhances security by restricting file access to a defined root directory, preventing unintended side effects and improving test isolation.

Co-authored-by: batazor111 <batazor111@gmail.com>
Copy link

cursor bot commented Sep 27, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

Copy link
Contributor

sourcery-ai bot commented Sep 27, 2025

Reviewer's Guide

This PR introduces a new pkg/fsroot package that wraps Go 1.25’s os.Root into a SafeFS utility for confined filesystem operations, then systematically migrates existing file and directory access across various modules and tests to use this secure API, eliminating direct os.* calls to prevent path traversal.

Sequence diagram for secure rule loading in loadRules (poc/cel/rules.go)

sequenceDiagram
    participant Caller
    participant SafeFS
    participant Directory
    participant File
    Caller->>SafeFS: OpenRoot(path)
    SafeFS->>Directory: Open(".")
    Directory->>SafeFS: ReadDir(-1)
    SafeFS->>Caller: files
    loop For each file
        Caller->>SafeFS: ReadFile(file.Name())
        SafeFS->>File: ReadFile(file.Name())
        File->>SafeFS: content
        SafeFS->>Caller: content
    end
Loading

Class diagram for the new SafeFS type in pkg/fsroot

classDiagram
    class SafeFS {
        - root: os.Root
        + ReadFile(name string) (data []byte, err error)
        + ReadDir(name string) ([]os.DirEntry, error)
        + Create(name string) (*os.File, error)
        + Open(name string) (*os.File, error)
        + Remove(name string) error
        + Stat(name string) (os.FileInfo, error)
        + WriteFile(name string, data []byte, perm os.FileMode) error
    }
    SafeFS o-- "1" os.Root: wraps
    class os.Root {
        + Open(name string) (*os.File, error)
        + ReadFile(name string) ([]byte, error)
        + ...
    }
Loading

File-Level Changes

Change Details Files
Introduce pkg/fsroot SafeFS wrapper around os.Root
  • Define SafeFS with confined methods: ReadFile, ReadDir, Create, Open, Remove, Stat, WriteFile
  • Implement OpenInRoot convenience for single-step root-bound access
  • Add comprehensive unit tests and example tests illustrating security guarantees
  • Provide README with API reference, usage examples, and migration guidance
pkg/fsroot/fsroot.go
pkg/fsroot/fsroot_test.go
pkg/fsroot/example_test.go
pkg/fsroot/README.md
Migrate loadRules to use os.OpenRoot in poc/cel
  • Initialize os.Root for the target rules directory
  • Open and read directory entries via root.Open � root.ReadDir
  • Read file contents securely using root.ReadFile
poc/cel/rules.go
Secure fixture cleanup and reading in pkg/s3 tests
  • Open fixtures folder via os.OpenRoot
  • Remove downloaded file using root.Remove
  • Open and read test file using root.Open
pkg/s3/s3_test.go
Restrict protoc-gen-go-orm test file reads to output directory
  • Open output directory via os.OpenRoot
  • Replace os.ReadFile calls with root.ReadFile for Mongo, RAM, and Postgres ORM tests
pkg/protoc/protoc-gen-go-orm/mongo_orm_test.go
pkg/protoc/protoc-gen-go-orm/ram_orm_test.go
pkg/protoc/protoc-gen-go-orm/postgres_orm_test.go
Bind protoc-gen-rich-model test access to output directory
  • Open outputDir with os.OpenRoot
  • Read generated link_ddd.go via root.ReadFile
pkg/protoc/protoc-gen-rich-model/rich_model_test.go
Use os.OpenRoot to remove SQLite database file securely
  • Extract directory and filename from ENV path
  • Open directory via os.OpenRoot and remove file with root.Remove
boundaries/link/internal/infrastructure/repository/crud/sqlite/sqlite_test.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

cursoragent and others added 2 commits September 27, 2025 18:42
Co-authored-by: batazor111 <batazor111@gmail.com>
Co-authored-by: batazor111 <batazor111@gmail.com>
Co-authored-by: batazor111 <batazor111@gmail.com>
Co-authored-by: batazor111 <batazor111@gmail.com>
@batazor batazor marked this pull request as ready for review October 13, 2025 07:55
@batazor batazor enabled auto-merge October 13, 2025 07:55
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Consider using your new fsroot.SafeFS abstraction instead of raw os.OpenRoot calls everywhere to reduce boilerplate and centralize error handling.
  • You have repeated os.OpenRoot(...)/defer root.Close() blocks in multiple tests—extract a small test helper to initialize and clean up the root FS to avoid copy-pasted code.
  • In loadRules, you could wrap the directory iteration and file reading into a helper method on SafeFS to simplify the function and improve readability.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider using your new fsroot.SafeFS abstraction instead of raw os.OpenRoot calls everywhere to reduce boilerplate and centralize error handling.
- You have repeated os.OpenRoot(...)/defer root.Close() blocks in multiple tests—extract a small test helper to initialize and clean up the root FS to avoid copy-pasted code.
- In loadRules, you could wrap the directory iteration and file reading into a helper method on SafeFS to simplify the function and improve readability.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
32.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@batazor batazor closed this Oct 13, 2025
auto-merge was automatically disabled October 13, 2025 07:57

Pull request was closed

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.

2 participants