Skip to content

Fix sandbox access to workdir secrets#366

Merged
ModerRAS merged 4 commits into
masterfrom
fix/sandbox-exclude-logs
Jun 2, 2026
Merged

Fix sandbox access to workdir secrets#366
ModerRAS merged 4 commits into
masterfrom
fix/sandbox-exclude-logs

Conversation

@ModerRAS

@ModerRAS ModerRAS commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • tighten Sandboxie portable box setup so the box import directory is created automatically before writing box definitions
  • keep Sandboxie as the enforcement layer: allow the app directory plus current-chat media directories, and close off workdir secrets such as logs, config, and sqlite data
  • add focused tests for closed log paths and missing box-directory creation

Validation

  • dotnet test TelegramSearchBot.LLM.Test/TelegramSearchBot.LLM.Test.csproj --filter "FullyQualifiedName~TelegramSearchBot.Test.Service.Tools.BashToolServiceTests|FullyQualifiedName~TelegramSearchBot.Test.Service.Tools.FileToolServiceTests"
  • dotnet test TelegramSearchBot.Test/TelegramSearchBot.Test.csproj --filter "FullyQualifiedName~SandboxieToolHostServiceTests"

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ModerRAS, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 22 minutes and 29 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3aa2c638-3068-4b00-b301-c17feb328df2

📥 Commits

Reviewing files that changed from the base of the PR and between 9a85966 and 82c7e22.

📒 Files selected for processing (4)
  • TelegramSearchBot.LLM.Test/Service/Tools/BashToolServiceTests.cs
  • TelegramSearchBot.LLM/Service/Tools/BashToolService.cs
  • TelegramSearchBot.Test/Service/AI/LLM/SandboxieToolHostServiceTests.cs
  • TelegramSearchBot/Service/AI/LLM/SandboxieToolHostService.cs
📝 Walkthrough

Walkthrough

This PR adds sandbox-based path validation to tool services. BashToolService and FileToolService now validate sandboxed tool execution against per-chat directory allow-lists, blocking access outside permitted roots (app base directory, per-chat media/file directories under Env.WorkDir, and optionally Env.SandboxieGroupFilesRoot). Changes include helpers for path normalization and OS-aware containment checking, along with comprehensive tests and Sandboxie configuration alignment.

Changes

Sandbox Path Restrictions for Tool Services

Layer / File(s) Summary
Bash tool sandbox path enforcement
TelegramSearchBot.LLM/Service/Tools/BashToolService.cs
ExecuteCommand adds early validation when sandboxed, delegating to internal helpers (TryGetSandboxCommandRestrictionError, IsPathInSandboxCommandAllowList) that resolve paths and verify containment against allowed roots per chatId using OS-specific comparison rules.
File tool sandbox path enforcement
TelegramSearchBot.LLM/Service/Tools/FileToolService.cs
Five file operation methods (ReadFile, WriteFile, EditFile, SearchText, ListFiles) now call TryValidateSandboxPath before proceeding. Internal helpers (IsPathInSandboxAllowList, GetSandboxAllowedRoots, IsPathUnderRoot, NormalizePath) enumerate allowed roots and enforce containment checks.
Sandbox restriction testing
TelegramSearchBot.LLM.Test/Service/Tools/BashToolServiceTests.cs, TelegramSearchBot.LLM.Test/Service/Tools/FileToolServiceTests.cs
BashToolServiceTests removes explanatory comments and adds three new tests covering work-directory rejection, BaseDirectory allowance, and per-chat root filtering. FileToolServiceTests adds two tests for sandboxed ListFiles rejection and allow-list validation.
Sandboxie configuration alignment
TelegramSearchBot/Service/AI/LLM/SandboxieToolHostService.cs, TelegramSearchBot.Test/Service/AI/LLM/SandboxieToolHostServiceTests.cs
SandboxieToolHostService updates the closed-path case from Logs to logs. The test creates logs directory and validates both ReadFilePath allowances for current-chat media and ClosedFilePath restrictions for Photos/Audios/Videos/Files/logs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ModerRAS/TelegramSearchBot#356: This PR's sandbox path validation in BashToolService and FileToolService extends the sandboxed ToolContext plumbing that sets IsSandboxed for tool execution within Sandboxie.

Poem

🐰 Paths now guarded by the rabbit's care,
Each sandbox gets its slice so fair,
Per-chat roots keep files secure,
While BaseDirectory stays pure,
Sandboxed tools can roam no more,
Confined within their allowed door! 🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly addresses the main objective: restricting sandboxed access to prevent traversal into workdir secrets, which is the core security fix across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/sandbox-exclude-logs

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@TelegramSearchBot.LLM/Service/Tools/BashToolService.cs`:
- Line 216: The sandbox validation uses ResolveFullPath(workingDirectory ??
AppContext.BaseDirectory) but execution actually uses Env.WorkDir, so make the
validation use the same default as execution: change the ResolveFullPath call
that sets workDir to use (workingDirectory ?? Env.WorkDir) instead of
AppContext.BaseDirectory; update any references in the BashToolService method
where workDir is validated to ensure it now validates the actual execution path
(symbols: ResolveFullPath, workingDirectory, AppContext.BaseDirectory,
Env.WorkDir, workDir).

In `@TelegramSearchBot.Test/Service/AI/LLM/SandboxieToolHostServiceTests.cs`:
- Around line 28-32: The assertions compare expected ClosedFilePath strings
without the trailing "\*" but BuildPortableBoxIni appends "\*" when a directory
exists, causing brittle failures; update the test to use the existing ClosedPath
helper (ClosedPath(Env.WorkDir, "Photos"), ClosedPath(Env.WorkDir, "Audios"),
ClosedPath(Env.WorkDir, "Videos"), ClosedPath(Env.WorkDir, "Files"), and
ClosedPath(Env.WorkDir, "logs")) for each Assert.Contains so the expected value
matches BuildPortableBoxIni's behavior regardless of whether the directory
exists; keep references to Env.WorkDir and ensure you call ClosedPath for each
asserted path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc260350-20cc-4811-aad7-0e35f4db8d34

📥 Commits

Reviewing files that changed from the base of the PR and between b9a5265 and 9a85966.

📒 Files selected for processing (6)
  • TelegramSearchBot.LLM.Test/Service/Tools/BashToolServiceTests.cs
  • TelegramSearchBot.LLM.Test/Service/Tools/FileToolServiceTests.cs
  • TelegramSearchBot.LLM/Service/Tools/BashToolService.cs
  • TelegramSearchBot.LLM/Service/Tools/FileToolService.cs
  • TelegramSearchBot.Test/Service/AI/LLM/SandboxieToolHostServiceTests.cs
  • TelegramSearchBot/Service/AI/LLM/SandboxieToolHostService.cs

return true;
}

var workDir = ResolveFullPath(workingDirectory ?? AppContext.BaseDirectory);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: Default path mismatch causes sandbox bypass.

When workingDirectory is null, the sandbox validation uses AppContext.BaseDirectory as the default (Line 216), but actual command execution uses Env.WorkDir (Line 106). Since Env.WorkDir itself is not in the allowed roots (only chat-specific subdirectories are), a sandboxed command with no explicit workingDirectory will:

  1. Pass validation (because AppContext.BaseDirectory is allowed)
  2. Execute in Env.WorkDir (which is not allowed, exposing logs, config, sqlite)

This defeats the sandbox restriction this PR aims to implement.

🔒 Proposed fix
-            var workDir = ResolveFullPath(workingDirectory ?? AppContext.BaseDirectory);
+            var workDir = ResolveFullPath(workingDirectory ?? Env.WorkDir);

This makes the validation check the same path that will actually be used for execution. Since Env.WorkDir is not in the allowed list, sandboxed commands without an explicit allowed workingDirectory will be correctly rejected.

📝 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
var workDir = ResolveFullPath(workingDirectory ?? AppContext.BaseDirectory);
var workDir = ResolveFullPath(workingDirectory ?? Env.WorkDir);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@TelegramSearchBot.LLM/Service/Tools/BashToolService.cs` at line 216, The
sandbox validation uses ResolveFullPath(workingDirectory ??
AppContext.BaseDirectory) but execution actually uses Env.WorkDir, so make the
validation use the same default as execution: change the ResolveFullPath call
that sets workDir to use (workingDirectory ?? Env.WorkDir) instead of
AppContext.BaseDirectory; update any references in the BashToolService method
where workDir is validated to ensure it now validates the actual execution path
(symbols: ResolveFullPath, workingDirectory, AppContext.BaseDirectory,
Env.WorkDir, workDir).

Comment thread TelegramSearchBot.Test/Service/AI/LLM/SandboxieToolHostServiceTests.cs Outdated
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

PR Check Report

Summary

Test Results

Platform Status Details
Ubuntu Passed Tests passed, artifacts uploaded
Windows Passed Tests passed, artifacts uploaded

Code Quality

  • Code formatting check
  • Security vulnerability scan
  • Dependency analysis
  • Code coverage collection

Test Artifacts

  • Test results artifacts count: 2
  • Code coverage uploaded to Codecov

Links


This report is auto-generated by GitHub Actions

@ModerRAS ModerRAS merged commit fe49fd9 into master Jun 2, 2026
5 checks passed
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