Skip to content

🛡️ Sentinel: [CRITICAL] Fix Path Traversal via Folder ID#310

Merged
abhimehro merged 8 commits intomainfrom
sentinel/fix-path-traversal-folder-id-2150753986649535080
Feb 19, 2026
Merged

🛡️ Sentinel: [CRITICAL] Fix Path Traversal via Folder ID#310
abhimehro merged 8 commits intomainfrom
sentinel/fix-path-traversal-folder-id-2150753986649535080

Conversation

@abhimehro
Copy link
Owner

This PR addresses a critical path traversal vulnerability where the application trusted "PK" (ID) fields from the external API and used them directly in file operations.

Changes:

  • Added FOLDER_ID_PATTERN regex (^[a-zA-Z0-9_.-]+$) to whitelist safe folder IDs.
  • Added validate_folder_id helper function.
  • Updated verify_access_and_get_folders, list_existing_folders, and create_folder in main.py to validate and reject invalid IDs.
  • Added regression test tests/test_folder_id_validation.py.
  • Updated .jules/sentinel.md with security learning.

This prevents attackers from exploiting the application via malicious API responses or MITM attacks injecting path traversal sequences.


PR created automatically by Jules for task 2150753986649535080 started by @abhimehro

🚨 Severity: CRITICAL
💡 Vulnerability: Path Traversal via Folder ID (PK) injection from API response.
🎯 Impact: An attacker controlling the API or MITM could inject path traversal payloads (e.g. ../../etc/passwd) into file operations.
🔧 Fix: Validated Folder IDs against a strict whitelist (^[a-zA-Z0-9_.-]+$).
✅ Verification: Added tests/test_folder_id_validation.py proving invalid IDs are rejected.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
@google-labs-jules
Copy link

👋 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 @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings February 17, 2026 11:04
@trunk-io
Copy link

trunk-io bot commented Feb 17, 2026

😎 Merged manually by @abhimehro - details.

@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

@gemini-code-assist
Copy link

Summary of Changes

Hello @abhimehro, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical path traversal vulnerability by implementing robust validation for folder IDs received from external APIs. By whitelisting acceptable characters and integrating this validation into key file operation functions, the application is now protected against malicious API responses or Man-in-the-Middle attacks attempting to inject path traversal sequences.

Highlights

  • New Regex Pattern: Introduced FOLDER_ID_PATTERN regex (^[a-zA-Z0-9_.-]+$) to whitelist safe folder IDs, preventing malicious input.
  • Validation Function: Implemented a validate_folder_id helper function to enforce the new ID pattern.
  • API Integration: Integrated folder ID validation into verify_access_and_get_folders, list_existing_folders, and create_folder functions in main.py to reject invalid IDs from external APIs.
  • Regression Test: Added a new regression test file (tests/test_folder_id_validation.py) to ensure the folder ID validation works as expected and prevents path traversal.
  • Security Documentation: Updated .jules/sentinel.md with a new security learning entry detailing the path traversal vulnerability and its prevention.
Changelog
  • .jules/sentinel.md
    • Added a new security learning entry for "Path Traversal via API Response (ID Validation)".
  • main.py
    • Defined FOLDER_ID_PATTERN regex for folder ID validation.
    • Added validate_folder_id function to check folder ID format.
    • Modified list_existing_folders to validate PK values using validate_folder_id.
    • Modified verify_access_and_get_folders to validate pk values using validate_folder_id.
    • Modified create_folder to validate PK values from API responses using validate_folder_id before returning them.
  • pyproject.toml
    • Added an empty [dependency-groups] section with a dev group.
  • tests/test_folder_id_validation.py
    • Added a new test file containing test_verify_access_and_get_folders_filters_malicious_ids to verify folder ID validation.
  • uv.lock
    • Added [package.metadata.requires-dev] section.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

# Function should filter out malicious IDs
result = m.verify_access_and_get_folders(mock_client, "valid_profile")

assert result is not None

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert result is not None

# Check that valid IDs are preserved
assert "Safe Folder" in result

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Check that valid IDs are preserved
assert "Safe Folder" in result
assert result["Safe Folder"] == "safe_id_123"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
# Check that valid IDs are preserved
assert "Safe Folder" in result
assert result["Safe Folder"] == "safe_id_123"
assert "Safe Folder 2" in result

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "Safe Folder" in result
assert result["Safe Folder"] == "safe_id_123"
assert "Safe Folder 2" in result
assert result["Safe Folder 2"] == "safe-id-456_789"

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert result["Safe Folder 2"] == "safe-id-456_789"

# Check that malicious IDs are removed
assert "Malicious Folder" not in result

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Check that malicious IDs are removed
assert "Malicious Folder" not in result
assert "Malicious Folder 2" not in result

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses a path traversal vulnerability by implementing whitelist-based validation for folder IDs (PKs) through the introduction of validate_folder_id. For further refinement, ensure that dot-only IDs like .. are explicitly blocked and consider reducing redundant logging in the folder creation logic.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens handling of API-provided folder IDs (“PK”) to mitigate traversal/injection risks by validating IDs before they’re used in API path construction and related operations.

Changes:

  • Added FOLDER_ID_PATTERN + validate_folder_id() in main.py and applied validation when listing/using folder PKs.
  • Updated folder listing/creation flows to filter or reject invalid PKs.
  • Added a regression test for malicious PKs and documented the security learning in .jules/sentinel.md (plus pyproject/lock metadata updates).

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
main.py Introduces folder-ID validation and applies it in folder list/create flows.
tests/test_folder_id_validation.py Adds regression coverage for filtering malicious PKs in verify_access_and_get_folders.
.jules/sentinel.md Documents the vulnerability/learning/prevention guidance.
pyproject.toml Adds a dependency-groups stanza (currently empty).
uv.lock Records additional metadata for dev requirements (currently empty).

Comment on lines +1420 to +1423
pk = str(body["group"]["PK"])
if not validate_folder_id(pk):
log.error(f"API returned invalid folder ID: {sanitize_for_log(pk)}")
return None
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The PR changes create_folder() behavior to return None when the API returns an invalid folder ID, but there is no regression test asserting this new security behavior. Add a test that mocks the POST response to return an invalid PK (e.g., .. or ../../etc/passwd) and asserts create_folder() returns None and logs an error.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +1420 to +1423
pk = str(body["group"]["PK"])
if not validate_folder_id(pk):
log.error(f"API returned invalid folder ID: {sanitize_for_log(pk)}")
return None
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

create_folder() logs an error after validate_folder_id(pk) fails, but validate_folder_id() already logs an error by default. This results in duplicate error lines for the same bad PK. Consider calling validate_folder_id(pk, log_errors=False) here (and keeping the more specific message), or removing the extra log.error to avoid noisy logs.

Copilot uses AI. Check for mistakes.
Comment on lines 1118 to +1129
def list_existing_folders(client: httpx.Client, profile_id: str) -> Dict[str, str]:
try:
data = _api_get(client, f"{API_BASE}/{profile_id}/groups").json()
folders = data.get("body", {}).get("groups", [])
return {
f["group"].strip(): f["PK"]
for f in folders
if f.get("group") and f.get("PK")
}
result = {}
for f in folders:
if not f.get("group") or not f.get("PK"):
continue
pk = str(f["PK"])
if validate_folder_id(pk):
result[f["group"].strip()] = pk
return result
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

list_existing_folders() now filters out invalid PK values via validate_folder_id(), but there is no test covering this new behavior. Add a regression test that mocks the /groups API response with a mix of valid and invalid PKs and asserts the invalid ones are excluded (mirroring the new security intent).

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +743 to +751
def validate_folder_id(folder_id: str, log_errors: bool = True) -> bool:
"""Validates folder ID (PK) format to prevent path traversal."""
if not folder_id:
return False
if not FOLDER_ID_PATTERN.match(folder_id):
if log_errors:
log.error(f"Invalid folder ID format: {sanitize_for_log(folder_id)}")
return False
return True
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

validate_folder_id() currently allows . and .. because FOLDER_ID_PATTERN permits dots. If a malicious API response returns .., it will pass validation and later be interpolated into URL path segments (e.g., /groups/{folder_id}), reintroducing a dot-segment traversal vector on servers/proxies that normalize paths. Add an explicit block for folder_id.strip() in (., ..) (similar to is_valid_folder_name) before the regex check.

Copilot uses AI. Check for mistakes.
abhimehro and others added 3 commits February 18, 2026 13:04
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

2 similar comments
@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

abhimehro and others added 2 commits February 18, 2026 13:05
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

1 similar comment
@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

@github-actions
Copy link

👋 Development Partner is reviewing this PR. Will provide feedback shortly.

@abhimehro abhimehro merged commit 5c20c27 into main Feb 19, 2026
15 checks passed
@abhimehro abhimehro deleted the sentinel/fix-path-traversal-folder-id-2150753986649535080 branch February 19, 2026 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants