Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Config:
max_comments: int
min_severity: str
resolve_outdated: bool
cache_path: str

# Context settings
context_enabled: bool
Expand Down Expand Up @@ -108,6 +109,11 @@ def from_env(cls) -> "Config":
max_comments = parse_int_env("INPUT_MAX_COMMENTS", 10)
resolve_outdated = os.environ.get("INPUT_RESOLVE_OUTDATED", "true").lower() == "true"

# Build cache path from user input
cache_dir = os.environ.get("INPUT_CACHE_DIR", "/tmp/reviewer")
cache_name = os.environ.get("INPUT_CACHE_NAME", "state")
cache_path = os.path.join(cache_dir, cache_name + ".json")
Copy link
Copy Markdown

@github-actions github-actions Bot Mar 23, 2026

Choose a reason for hiding this comment

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

🔒 Security | ❌ ERROR

User-controlled environment variables are used directly in os.path.join to construct a file path, enabling path traversal attacks. An attacker could set INPUT_CACHE_DIR to '/etc' and INPUT_CACHE_NAME to '../../passwd' to access or overwrite sensitive files.

Suggested change
cache_path = os.path.join(cache_dir, cache_name + ".json")
Validate and sanitize inputs before use:
import os, re
# Resolve cache_dir to absolute path and restrict to allowed base
cache_dir = os.path.abspath(os.environ.get('INPUT_CACHE_DIR', '/tmp/reviewer'))
if not cache_dir.startswith('/tmp'):
raise ValueError('Cache directory must be under /tmp')
# Strip path components from cache_name and allow only safe characters
cache_name = os.path.basename(os.environ.get('INPUT_CACHE_NAME', 'state'))
if not re.match(r'^[a-zA-Z0-9_-]+$', cache_name):
raise ValueError('Invalid cache name')
cache_path = os.path.join(cache_dir, cache_name + '.json')


return cls(
token=token,
provider=provider,
Expand All @@ -119,6 +125,7 @@ def from_env(cls) -> "Config":
max_comments=max_comments,
min_severity=min_severity,
resolve_outdated=resolve_outdated,
cache_path=cache_path,
context_enabled=context_enabled,
context_max_tokens=context_max_tokens,
repo_owner=repo_owner,
Expand Down