Skip to content

Command injection vulnerability in subprocess-based nodes #17

@GaijinKa

Description

@GaijinKa

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=False param
  • changing the user that executes the sh

References

CWE-78: OS Command Injection
OWASP Command Injection

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions