Skip to content

🛡️ Sentinel: [CRITICAL/HIGH] Fix environment leakage and path traversal vulnerabilities - #462

Open
heidi-dang wants to merge 1 commit into
feat/bootstrap-scaffoldfrom
sentinel/fix-env-leak-path-traversal-10764456563853644933
Open

🛡️ Sentinel: [CRITICAL/HIGH] Fix environment leakage and path traversal vulnerabilities#462
heidi-dang wants to merge 1 commit into
feat/bootstrap-scaffoldfrom
sentinel/fix-env-leak-path-traversal-10764456563853644933

Conversation

@heidi-dang

Copy link
Copy Markdown
Owner

🚨 Severity: CRITICAL

💡 Vulnerability:

  1. scripts/03_unit_test_gate.py leaked the full host environment (including OPENAI_API_KEY) to untrusted code being tested.
  2. heidi_engine/telemetry.py and dashboard.py were vulnerable to path traversal via the run_id parameter.

🎯 Impact:

  1. Maliciously generated code could exfiltrate sensitive API keys or other secrets from the environment.
  2. A malicious run_id could be used to read or write files anywhere on the system accessible to the user, potentially compromising the host.

🔧 Fix:

  1. Restricted the environment in subprocess.run to a safe whitelist.
  2. Implemented sanitize_run_id using Path(run_id).name with explicit checks for .. and empty strings.
  3. Fixed a related NameError in telemetry.py cache logic and cleaned up redundant blocks.
  4. Used textwrap.indent to ensure proper nesting of injected code in unit test wrappers.

✅ Verification:

  1. Verified environment isolation with a script that confirmed sensitive keys were inaccessible to child processes.
  2. Verified path traversal protection with a script testing various malicious run_id inputs like ../.
  3. All existing unit tests passed.

PR created automatically by Jules for task 10764456563853644933 started by @heidi-dang

- Restrict environment variables in unit test gate to prevent secret leakage.
- Implement sanitize_run_id to prevent path traversal in telemetry and dashboard.
- Use textwrap.indent for safe code injection in unit tests.
- Fix NameError in telemetry cache logic.
- Update Sentinel journal with new learnings.
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces path traversal protection by adding and applying a sanitize_run_id helper function in both heidi_engine/dashboard.py and heidi_engine/telemetry.py. It also enhances the security of the unit test gate script by properly indenting executed code and restricting environment variables passed to subprocesses to prevent credential leaks. The review feedback suggests raising a ValueError instead of returning a fallback string in sanitize_run_id to prevent silent failures and state collisions, and recommends importing the helper function to eliminate code duplication.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread heidi_engine/telemetry.py
Comment on lines +400 to +418
def sanitize_run_id(run_id: str) -> str:
"""
Sanitize run_id to prevent path traversal.

SECURITY:
- Uses Path(run_id).name to isolate filename
- Rejects '..' or empty strings
"""
if not run_id:
return "invalid_run_id"

# Get only the last component of the path
safe_id = Path(run_id).name

# Check for dangerous or empty results
if safe_id in ("..", ".", ""):
return "invalid_run_id"

return safe_id

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

Returning a fallback string like "invalid_run_id" instead of raising an exception is a security and correctness issue. If an invalid or malicious RUN_ID is provided via the environment, get_run_id() will set RUN_ID to "invalid_run_id". Since "invalid_run_id" is truthy, the fallback UUID generation block is bypassed, and the application will silently run using a shared, static directory (runs/invalid_run_id). This can lead to state collision, data corruption, or unauthorized data sharing between different invalid runs.

Instead, raise a ValueError to fail-fast and prevent running under an invalid configuration.

Suggested change
def sanitize_run_id(run_id: str) -> str:
"""
Sanitize run_id to prevent path traversal.
SECURITY:
- Uses Path(run_id).name to isolate filename
- Rejects '..' or empty strings
"""
if not run_id:
return "invalid_run_id"
# Get only the last component of the path
safe_id = Path(run_id).name
# Check for dangerous or empty results
if safe_id in ("..", ".", ""):
return "invalid_run_id"
return safe_id
def sanitize_run_id(run_id: str) -> str:
"""
Sanitize run_id to prevent path traversal.
SECURITY:
- Uses Path(run_id).name to isolate filename
- Rejects '..' or empty strings
"""
if not run_id:
raise ValueError("Run ID cannot be empty")
# Get only the last component of the path
safe_id = Path(run_id).name
# Check for dangerous or empty results
if safe_id in ("..", ".", ""):
raise ValueError(f"Invalid run ID: {run_id}")
return safe_id

Comment thread heidi_engine/dashboard.py
Comment on lines +135 to +153
def sanitize_run_id(run_id: str) -> str:
"""
Sanitize run_id to prevent path traversal.

SECURITY:
- Uses Path(run_id).name to isolate filename
- Rejects '..' or empty strings
"""
if not run_id:
return "invalid_run_id"

# Get only the last component of the path
safe_id = Path(run_id).name

# Check for dangerous or empty results
if safe_id in ("..", ".", ""):
return "invalid_run_id"

return safe_id

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To avoid code duplication of a security-critical function, import sanitize_run_id directly from heidi_engine.telemetry instead of redefining it here. This ensures consistent sanitization behavior across both modules and simplifies future maintenance.

from heidi_engine.telemetry import sanitize_run_id

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