🛡️ Sentinel: [CRITICAL] Fix prefix-matching path traversal bypass in Lua IO module#180
🛡️ Sentinel: [CRITICAL] Fix prefix-matching path traversal bypass in Lua IO module#180mleem97 wants to merge 1 commit into
Conversation
…Lua IO module Added a trailing directory separator to the base directory before performing the `StartsWith` boundary check in `GregIoLuaModule.cs`. This prevents malicious path prefix bypasses (e.g., escaping `/mods/modA` via `/mods/modA_secret`). Also safely handles exact matches to the base directory itself.
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
| Duplication | 0 |
AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Pull Request Overview
While this PR addresses a critical path traversal vulnerability, the changes lack accompanying unit tests to verify the fix and prevent future regressions. This is particularly concerning as the logic resides in a complex file (GregIoLuaModule.cs) that is currently uncovered by the test suite. Additionally, the implementation of ResolveSafe is computationally expensive as it recalculates normalized paths on every invocation; refactoring this to pre-calculate values during module registration would improve performance. One minor optimization regarding string allocations in prefix checking was also identified.
About this PR
- This PR fixes a critical security vulnerability but does not include any new or updated unit tests to verify the fix. Relying on manual verification for path traversal logic is high-risk, especially for the GregIoLuaModule which is complex and lacks automated coverage. Please add automated tests to prevent future regressions.
Test suggestions
- Attempt to access a sibling directory that shares a prefix with the sandbox name (e.g., accessing modA_secret when authorized for modA).
- Access a valid file within the authorized sandbox directory.
- Access the sandbox directory itself using an exact match path.
- Attempt to escape the sandbox using path traversal sequences like '../'.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Attempt to access a sibling directory that shares a prefix with the sandbox name (e.g., accessing modA_secret when authorized for modA).
2. Access a valid file within the authorized sandbox directory.
3. Access the sandbox directory itself using an exact match path.
4. Attempt to escape the sandbox using path traversal sequences like '../'.
TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback
| private static string ResolveSafe(string dataDir, string relativePath) | ||
| { | ||
| if (string.IsNullOrWhiteSpace(relativePath)) | ||
| throw new InvalidOperationException("Path cannot be empty"); | ||
|
|
||
| // Prevent path traversal | ||
| string normalized = relativePath.Replace('/', Path.DirectorySeparatorChar); | ||
| string fullPath = Path.GetFullPath(Path.Combine(dataDir, normalized)); | ||
| string dataDirFull = Path.GetFullPath(dataDir); | ||
|
|
||
| // Ensure directory ends with slash to prevent prefix-matching traversal (e.g. /modA_secret bypassing /modA) | ||
| string dataDirFullWithSlash = dataDirFull; | ||
| if (!dataDirFullWithSlash.EndsWith(Path.DirectorySeparatorChar.ToString())) | ||
| dataDirFullWithSlash += Path.DirectorySeparatorChar; | ||
|
|
||
| if (!fullPath.StartsWith(dataDirFullWithSlash, StringComparison.OrdinalIgnoreCase) && !fullPath.Equals(dataDirFull, StringComparison.OrdinalIgnoreCase)) | ||
| throw new UnauthorizedAccessException($"Access denied: path escapes sandbox ('{relativePath}')"); | ||
|
|
||
| return fullPath; | ||
| } |
There was a problem hiding this comment.
🟡 MEDIUM RISK
Suggestion: The ResolveSafe method recalculates the absolute path of the sandbox root on every call; pre-calculating these values in the Register method and capturing them in closures would improve performance. More importantly, this method serves as the security boundary for the Lua sandbox and currently lacks unit test coverage in this complex file. It is essential to add tests covering valid relative paths, path traversal (../), absolute paths, and the specific prefix-matching bypass this PR addresses.
GregIoLuaModule.csdue to a missing trailing slash in theStartsWithboundary check./mods/modA->/mods/modA_secret/file.txt).StartsWithvalidation, and added an exact match check.dotnet build && dotnet test.PR created automatically by Jules for task 16388458994987341228 started by @mleem97