🛡️ Sentinel: [CRITICAL] Fix path traversal in module resolution#254
🛡️ Sentinel: [CRITICAL] Fix path traversal in module resolution#254bashandbone wants to merge 1 commit into
Conversation
Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
|
👋 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. |
Reviewer's guide (collapsed on small PRs)Reviewer's GuideFixes a critical path traversal bug in the TypeScript dependency extractor’s manual path normalization, tightens lifetime usage in rule-engine helpers, and documents the vulnerability and remediation in a Sentinel note. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Pull request overview
This PR addresses a critical path-normalization flaw in the TypeScript dependency extractor’s manual fallback module resolution, aiming to prevent unsafe or incorrect handling of .. (ParentDir) components. It also includes a small refactor to simplify lifetimes in rule-engine variable checking helpers and adds an internal Sentinel note documenting the vulnerability.
Changes:
- Fix manual path normalization for TypeScript relative module resolution by handling
ParentDircomponents based on the previous component state (RootDir/Prefix/Normal/empty). - Simplify helper function signatures in the rule engine by removing unnecessary explicit lifetimes.
- Add internal Sentinel documentation describing the vulnerability, learnings, and prevention guidance.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
crates/rule-engine/src/check_var.rs |
Removes unnecessary lifetime parameters from internal variable-check helper functions. |
crates/flow/src/incremental/extractors/typescript.rs |
Updates manual path component normalization to safely handle ParentDir components when canonicalization fails. |
.jules/sentinel.md |
Adds an internal note documenting the path traversal vulnerability and prevention guidance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // If canonicalize fails (file doesn't exist), manually resolve | ||
| let mut components = Vec::new(); | ||
| for component in resolved.components() { | ||
| match component { | ||
| std::path::Component::ParentDir => { | ||
| components.pop(); | ||
| } | ||
| std::path::Component::ParentDir => match components.last() { | ||
| Some(std::path::Component::RootDir) | ||
| | Some(std::path::Component::Prefix(_)) => {} | ||
| Some(std::path::Component::Normal(_)) => { | ||
| components.pop(); | ||
| } | ||
| _ => components.push(component), | ||
| }, |
|
|
||
| ## 2024-05-22 - [Fix path traversal vulnerability in module resolution] | ||
| **Vulnerability:** The manual path resolution fallback in the TypeScript extractor popped path components unconditionally when encountering `..` (ParentDir), ignoring edge cases where `..` escapes the root directory or when leading `..` components should be preserved. |
| @@ -0,0 +1,5 @@ | |||
|
|
|||
| ## 2024-05-22 - [Fix path traversal vulnerability in module resolution] | |||
| let mut components = Vec::new(); | ||
| for component in resolved.components() { | ||
| match component { | ||
| std::path::Component::ParentDir => { | ||
| components.pop(); | ||
| } | ||
| std::path::Component::ParentDir => match components.last() { | ||
| Some(std::path::Component::RootDir) | ||
| | Some(std::path::Component::Prefix(_)) => {} |
🚨 Severity: CRITICAL
💡 Vulnerability: The manual path resolution fallback in the TypeScript dependency extractor (
crates/flow/src/incremental/extractors/typescript.rs) incorrectly resolved..(ParentDir) components when normalizing paths. It unconditionally popped the last component, which could allow relative path traversal to escape the root directory or lose essential parent references like../../foo.🎯 Impact: This allowed arbitrary file read or incorrect dependency extraction, as malformed paths could lead to traversing above root directories, exposing sensitive files, or causing unexpected module caching behavior across different projects on the same file system.
🔧 Fix: Updated the
std::path::Component::ParentDirmatch case to properly evaluate what the last component is before popping. It will ignore popping if it hitsRootDirorPrefix, pop only if it is aNormalcomponent, and pushParentDirif it reaches an unresolved or initial state (e.g.../../).✅ Verification: Ran
cargo test -p thread-flow --test extractor_typescript_testswhich covers relative path resolution and module extractions, ensuring no regressions. Additionally ran lintscargo clippy --workspace -- -D warnings.PR created automatically by Jules for task 2805762371481294443 started by @bashandbone
Summary by Sourcery
Fix path normalization in the TypeScript dependency extractor to prevent unsafe path traversal and make minor adjustments to rule-engine variable checking signatures, while adding internal security documentation for the vulnerability.
Bug Fixes:
ParentDircomponents during manual path resolution.Enhancements:
Documentation: