-
Notifications
You must be signed in to change notification settings - Fork 29
Description
location: https://github.com/square/git-fastclone/tree/master/lib
Overview of the Vulnerability
The git-fastclone.rb script contains insecure file handling practices that can be exploited to perform unauthorized file access and potentially lead to command injection. This vulnerability is exacerbated by the potential for chaining with other vulnerabilities, such as command execution without proper validation.
Affected Components
Script: git-fastclone.rb
- Functions:
File.openDir.globFileUtils.mkdir_pFile.expand_path
Vulnerability Details
1) Insecure File Handling
- File.open:
File.open(lock_file_name, File::RDWR | File::CREAT, 0o644)
Issue: lock_file_name is not validated, allowing potential unauthorized file access.
- Dir.glob:
dest_with_dotfiles = Dir.glob("#{clone_dest}/*", File::FNM_DOTMATCH)
Issue: clone_dest is not sanitized, allowing directory traversal attacks.
- FileUtils.mkdir_p:
FileUtils.mkdir_p(reference_dir)
Issue: reference_dir is created without validation, possibly leading to unintended directories.
- File.expand_path:
File.expand_path(hook_command)
Issue: hook_command is expanded without validation, allowing path traversal.
2) Potential Command Injection
If an attacker can manipulate file paths and place malicious scripts, they might exploit the application's command execution logic.
Steps to Reproduce
1) Directory Traversal and File Manipulation
- Inject a malicious file path into
clone_destand observe unauthorized file access. - Example: Set
clone_destto a path containing../../to traverse directories.
Example Code to Reproduce
# Simulated malicious input
clone_dest = "/tmp/../../../../etc/passwd"
# Insecure file handling
dest_with_dotfiles = Dir.glob("#{clone_dest}/*", File::FNM_DOTMATCH)
puts dest_with_dotfiles
2) Steps to Reproduce Command Injection
- Set Up the Environment:
- Create a directory that the application will scan and potentially execute scripts from.
- In this example, we'll use
/tmp/attacker-controlled.
- Create a Malicious Script:
- Place a script named
malicious.shin the directory that will execute arbitrary commands. - The script could contain something harmful like deleting files or echoing a message to demonstrate the exploit.
- Execute the Vulnerable Code:
- Run the application or the vulnerable code snippet with the attacker-controlled directory.
Detailed Steps
- Create the Attacker-Controlled Directory:
mkdir -p /tmp/attacker-controlled
- Create the Malicious Script:
echo 'echo "Malicious code executed"; rm -rf /important/data' > /tmp/attacker-controlled/malicious.sh
chmod +x /tmp/attacker-controlled/malicious.sh
- Run the Vulnerable Code:
- Assume the following Ruby code is part of the application:
clone_dest = "/tmp/attacker-controlled"
dest_with_dotfiles = Dir.glob("#{clone_dest}/*", File::FNM_DOTMATCH)
dest_with_dotfiles.each do |file|
system("sh #{file}") # This executes the malicious script
end
- Execute the Vulnerable Script:
- Run the Ruby script or the part of the application where the vulnerable code exists.
- The malicious script should execute, demonstrating the command injection vulnerability.
Expected Outcome
- When the vulnerable code executes, you should see the output from the malicious script:
Malicious code executed - Additionally, if the script contained a harmful command like rm
-rf /important/data, it would execute that command, demonstrating the potential severity of the vulnerability.
Impact
- Confidentiality: Unauthorized access to sensitive files.
- Integrity: Potential file modification leading to corrupted or malicious files.
- Availability: Disruption of service by altering or deleting critical files.
Conclusion:
Properly sanitizing and validating file paths, restricting file permissions, and securely handling command execution can significantly reduce the risk of exploitation. Implementing these mitigations will help protect against unauthorized access and potential command injection vulnerabilities.
Mitigation Code Example:
require 'pathname'
# Example of safer file handling with Pathname
def secure_file_open(path, mode)
safe_path = Pathname.new(path).cleanpath
raise "Invalid path" unless safe_path.ascend.all? { |p| p.absolute? }
File.open(safe_path, mode)
end
# Usage of the secure_file_open method
lock_file_name = "/some/lock/file" # This should be derived safely
secure_file_open(lock_file_name, File::RDWR | File::CREAT, 0o644) do |file|
# Perform operations on the file
end
# Example of secure directory traversal prevention
def secure_dir_glob(pattern)
safe_pattern = Pathname.new(pattern).cleanpath.to_s
raise "Invalid pattern" if safe_pattern.include?("..")
Dir.glob(safe_pattern, File::FNM_DOTMATCH)
end
# Usage of the secure_dir_glob method
clone_dest = "/some/clone/dest"
dest_with_dotfiles = secure_dir_glob("#{clone_dest}/*")