Split DANGEROUS_PATHS into two categories: 1. DANGEROUS_SYSTEM_PATHS: Block path AND all subdirectories (e.g., /etc, /etc/passwd, /var/log/auth.log) 2. DANGEROUS_HOME_CONTAINERS: Block ONLY exact match (e.g., /home is blocked but /home/user/project passes through) This fixes the issue where /home/user/project was incorrectly blocked by is_dangerous_path(). Subdirectory access control for home directories is properly delegated to is_home_directory_root() in resolve_and_validate_path(). Addresses review feedback from @chatgpt-codex-connector about blocking all home directory subpaths.
153 lines
3.9 KiB
Python
153 lines
3.9 KiB
Python
"""
|
|
Security configuration and path validation constants
|
|
|
|
This module contains security-related constants and configurations
|
|
for file access control.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
# Dangerous system paths - block these AND all their subdirectories
|
|
# These are system directories where user code should never reside
|
|
DANGEROUS_SYSTEM_PATHS = {
|
|
"/",
|
|
"/etc",
|
|
"/usr",
|
|
"/bin",
|
|
"/var",
|
|
"/root",
|
|
"C:\\",
|
|
"C:\\Windows",
|
|
"C:\\Program Files",
|
|
}
|
|
|
|
# User home container paths - block ONLY the exact path, not subdirectories
|
|
# Subdirectory access (e.g., /home/user/project) is controlled by is_home_directory_root()
|
|
# This allows users to work in their home subdirectories while blocking overly broad access
|
|
DANGEROUS_HOME_CONTAINERS = {
|
|
"/home",
|
|
"C:\\Users",
|
|
}
|
|
|
|
# Combined set for backward compatibility
|
|
DANGEROUS_PATHS = DANGEROUS_SYSTEM_PATHS | DANGEROUS_HOME_CONTAINERS
|
|
|
|
# Directories to exclude from recursive file search
|
|
# These typically contain generated code, dependencies, or build artifacts
|
|
EXCLUDED_DIRS = {
|
|
# Python
|
|
"__pycache__",
|
|
".venv",
|
|
"venv",
|
|
"env",
|
|
".env",
|
|
"*.egg-info",
|
|
".eggs",
|
|
"wheels",
|
|
".Python",
|
|
".mypy_cache",
|
|
".pytest_cache",
|
|
".tox",
|
|
"htmlcov",
|
|
".coverage",
|
|
"coverage",
|
|
# Node.js / JavaScript
|
|
"node_modules",
|
|
".next",
|
|
".nuxt",
|
|
"bower_components",
|
|
".sass-cache",
|
|
# Version Control
|
|
".git",
|
|
".svn",
|
|
".hg",
|
|
# Build Output
|
|
"build",
|
|
"dist",
|
|
"target",
|
|
"out",
|
|
# IDEs
|
|
".idea",
|
|
".vscode",
|
|
".sublime",
|
|
".atom",
|
|
".brackets",
|
|
# Temporary / Cache
|
|
".cache",
|
|
".temp",
|
|
".tmp",
|
|
"*.swp",
|
|
"*.swo",
|
|
"*~",
|
|
# OS-specific
|
|
".DS_Store",
|
|
"Thumbs.db",
|
|
# Java / JVM
|
|
".gradle",
|
|
".m2",
|
|
# Documentation build
|
|
"_build",
|
|
"site",
|
|
# Mobile development
|
|
".expo",
|
|
".flutter",
|
|
# Package managers
|
|
"vendor",
|
|
}
|
|
|
|
|
|
def is_dangerous_path(path: Path) -> bool:
|
|
"""
|
|
Check if a path is in or under a dangerous directory.
|
|
|
|
This function handles two categories of dangerous paths differently:
|
|
|
|
1. System paths (DANGEROUS_SYSTEM_PATHS): Block the path AND all subdirectories.
|
|
Example: /etc is dangerous, so /etc/passwd is also blocked.
|
|
|
|
2. Home containers (DANGEROUS_HOME_CONTAINERS): Block ONLY the exact path.
|
|
Example: /home is blocked, but /home/user/project is allowed.
|
|
Subdirectory access control is delegated to is_home_directory_root().
|
|
|
|
Args:
|
|
path: Path to check
|
|
|
|
Returns:
|
|
True if the path is dangerous and should not be accessed
|
|
|
|
Security:
|
|
Fixes path traversal vulnerability (CWE-22) while preserving
|
|
user access to home subdirectories.
|
|
"""
|
|
try:
|
|
resolved = path.resolve()
|
|
|
|
# Check 1: Root directory (filesystem root)
|
|
if resolved.parent == resolved:
|
|
return True
|
|
|
|
# Check 2: System paths - block exact match AND all subdirectories
|
|
for dangerous in DANGEROUS_SYSTEM_PATHS:
|
|
# Skip root "/" - already handled above
|
|
if dangerous == "/":
|
|
continue
|
|
|
|
dangerous_path = Path(dangerous)
|
|
# is_relative_to() correctly handles both exact matches and subdirectories
|
|
# Works properly on Windows with paths like "C:\" and "C:\Windows"
|
|
if resolved == dangerous_path or resolved.is_relative_to(dangerous_path):
|
|
return True
|
|
|
|
# Check 3: Home containers - block ONLY exact match
|
|
# Subdirectories like /home/user/project should pass through here
|
|
# and be handled by is_home_directory_root() in resolve_and_validate_path()
|
|
for container in DANGEROUS_HOME_CONTAINERS:
|
|
container_path = Path(container)
|
|
if resolved == container_path:
|
|
return True
|
|
|
|
return False
|
|
|
|
except Exception:
|
|
return True # If we can't resolve, consider it dangerous
|