-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Description
Nodes that invoke executables through subprocesses are vulnerable to command injection attacks. User-supplied strings used in shell script templating are not properly sanitized, allowing attackers to terminate the intended command and execute arbitrary commands.
Severity
High - Command injection allows arbitrary code execution
The severity is mitigated due to the constraint that allows only admins to set parameters in the pipeline
Vector
An attacker can inject malicious commands by using shell control operators in input parameters.
For example, using || evil_command; will:
- Terminate the current command execution
- Execute the injected command (echo "test" > test.json)
- Create a file with attacker-controlled content
Affected Component
_audio_rtp node:
process_log_level - ffmpeg logging level
_video_rtp node:
process_log_level - ffmpeg logging level
_videostream_ffmpeg node:
dst_host - destination host
process_log_level - ffmpeg logging level
Vulnerable Code Pattern
# The vulnerable subprocess invocation
self._ffmpeg_proc = subprocess.Popen(
['sh', self.ffmpeg_launcher],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
bufsize=10**8,
)
The ffmpeg_launcher file is a shell script that contains templated user input.
When this script is executed by sh, any injected commands will be executed.
Example Attack
# Example injection in dst_host parameter:
dst_host = "127.0.0.1 || echo 'malicious' > /tmp/pwned.txt; #"
# This creates a shell script containing:
# ffmpeg -i 127.0.0.1 || echo 'malicious' > /tmp/pwned.txt; # ...
# When executed by sh, this will run the injected command
# Example injection in logging level:
log_level = "info || rm -rf /important/data; #"
Impact
- Arbitrary command execution on the host system
- Data exfiltration through file creation or network requests
- System compromise depending on process privileges
- Denial of service through resource exhaustion or critical file deletion
Recommended Fixes
- Input Validation: Implement strict validation and sanitization for all user inputs used in the shell script template
- Direct Command Execution: Instead of templating a shell script file, pass arguments directly to the subprocess
- Escape Shell Metacharacters: If shell script templating is necessary, properly escape all special characters
- Least Privilege: Run subprocesses with minimal required permissions
Recommended Approach
Option 1: Direct subprocess invocation (Preferred)
self._ffmpeg_proc = subprocess.Popen(
['ffmpeg', '-loglevel', log_level, '-i', dst_host, ...],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
bufsize=10**8,
)
Option 2: Proper input sanitization
import shlex
# Sanitize user inputs before templating
safe_dst_host = shlex.quote(dst_host)
safe_log_level = shlex.quote(log_level)
# Use sanitized values in template
template = f"ffmpeg -loglevel {safe_log_level} -i {safe_dst_host} ..."
Option 3: Avoid shell execution
subprocess.Popen(['/path/to/ffmpeg', arg1, arg2, ...], ...)
Option 4: Limiting the permission of subprocess execution
- pass the
Shell=Falseparam - changing the user that executes the
sh