Skip to content
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

Arbitrary code execution vulnerability (or intended behavior?) #507

Open
panzi opened this issue Jun 14, 2024 · 0 comments
Open

Arbitrary code execution vulnerability (or intended behavior?) #507

panzi opened this issue Jun 14, 2024 · 0 comments

Comments

@panzi
Copy link

panzi commented Jun 14, 2024

Variable substitution and command substitution is done in two passes. This means if variable substitution results in a string containing $(command) that command is executed. I think this is unexpected, it isn't mentioned in the README in the section Command Substitution. This further means if some seemingly innocuous environment variables are user controlled and then referenced in the .env file this will execute any command in them.

This can be fixed by doing both variable substitution and command substitution in one pass instead of two.

(Personally I don't think command substitution is a good feature anyway, and it should be at least deactivated by default.)

Steps to reproduce

Put this in a .env file:

FOO='$'
BAR='(date)'
BAZ="$FOO$BAR"

Then run e.g.:

dotenv -f test.env ruby -e 'puts ENV.select {|k| %w(FOO BAR BAZ).include? k}'

Which prints:

{"FOO"=>"$", "BAR"=>"(date)", "BAZ"=>"Fr 14 Jun 2024 17:49:33 CEST"}

The command substitution doesn't need to be split over several variables, I just did this to demonstrate that even if that is done it works. Also the variables containing the command substitution syntax don't need to come from the .env file. They could be already in the environment. While I can't think of a situation where user input may control an environment variable that then is used in a .env file right off my head, I still consider that a potential problem. There's probably some obscure script somewhere that uses things like that. (The only similar situation I can think of are classical CGI scripts where HTTP headers are passed as environment variables, but Ruby isn't usually used as a CGI script and even then the HTTP header variables need to be referenced in the .env file, which is unlikely.)

Expected behavior

I think it should print this, and don't execute any commands:

{"FOO"=>"$", "BAR"=>"(date)", "BAZ"=>"$(date)"}

Actual behavior

Executes the command date in this case, or any command generally.

System configuration

dotenv version: dotenv 3.1.2

Ruby version: ruby 3.3.2 (2024-05-30 revision e5a195edf6) [x86_64-linux]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant