-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Fix path injection in addons #5667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,36 @@ | ||
| import json | ||
| import os | ||
| import re | ||
| import subprocess | ||
|
|
||
| obj = json.load(open("/etc/fluid/config/config.json")) | ||
|
|
||
| mount_point = obj["mounts"][0]["mountPoint"] | ||
| target_path = obj["targetPath"] | ||
|
|
||
| # Normalize first to resolve redundant separators, '.' and '..' components | ||
| target_path = os.path.normpath(target_path) | ||
|
|
||
| # Validate that the normalized path is an absolute POSIX path | ||
| if not os.path.isabs(target_path) or not target_path.startswith('/'): | ||
| print(f"Error: target_path must be absolute: {target_path}") | ||
| exit(1) | ||
|
|
||
| # Safety check: ensure no '..' components remain after normalization | ||
| if '..' in target_path.split('/'): | ||
| print(f"Error: Path traversal using '..' is not allowed in target_path: {target_path}") | ||
| exit(1) | ||
|
|
||
| # Validate that the path contains only safe characters | ||
| if not re.match(r'^[/a-zA-Z0-9._-]+$', target_path): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| print(f"Error: target_path contains invalid characters: {target_path}") | ||
| exit(1) | ||
|
|
||
| # Prevent mounting on the root directory | ||
| if target_path == '/': | ||
| print("Error: target_path resolves to the root directory '/' and is not allowed.") | ||
| exit(1) | ||
|
Comment on lines
+12
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section has critical vulnerabilities. The current root directory check can be bypassed using paths with double leading slashes (e.g., target_path = os.path.normpath(target_path)
if target_path.startswith('//') and not target_path.startswith('///'):
target_path = '/' + target_path.lstrip('/')
# Validate that the normalized path is an absolute POSIX path
if not os.path.isabs(target_path) or not target_path.startswith('/'):
print(f"Error: target_path must be absolute: {target_path}")
exit(1)
# Safety check: ensure no '..' components remain after normalization
if '..' in target_path.split('/'):
print(f"Error: Path traversal using '..' is not allowed in target_path: {target_path}")
exit(1)
# Validate that the path contains only safe characters
if not re.fullmatch(r'^[/a-zA-Z0-9._-]+$', target_path):
print(f"Error: target_path contains invalid characters: {target_path}")
exit(1)
# Prevent mounting on the root directory
if target_path == '/':
print("Error: target_path resolves to the root directory '/' and is not allowed.")
exit(1) |
||
|
|
||
| os.makedirs(target_path, exist_ok=True) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The normalized if target_path == '/':
print("Error: target_path resolves to the root directory '/' and is not allowed.")
exit(1)
os.makedirs(target_path, exist_ok=True) |
||
|
|
||
| if len(mount_point.split(":")) != 2: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The path traversal check for '..' is performed before normalization. This creates a gap where paths like '/path/./subdir' or paths with multiple slashes would pass this check but might represent the same file system location as a path with '..'. While not directly a '..' bypass, checking before normalization means you're not validating the canonical form of the path. If normalization is moved to occur first (as suggested in another comment), this check can serve as a post-normalization safety check to catch any remaining '..' components, which should not exist in a properly normalized absolute path.