prevent arbitrary command execution via URL when using --defaultURLHandler #1003
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I've just seen changes in 1.3.16, and I think #996 points to a security flaw (which was there already, just happened to see it because of this change). In this version, when using
--defaultURLHandler favorite-browser
, opening an URL will execute a shell process (child_process.exec(...)
) to run the following command:favorite-browser "THE_URL"
Although
THE_URL
has some URL-encoded characters, this still leaves plenty of potential for arbitrary command execution via a malicious URL in a Teams message. In particular, the following characters are not encoded in the path of an URL:$
,(
,)
.Here is a way to exploit that:
https://google.com/$(sudo$IFS$(true)shutdown$IFS$(true)-h$IFS$(true)now)
$IFS
is substituted with some space characters$(true)
is substituted with empty string, it's used here to separate$IFS
and whatever followssudo shutdown -h now
is the resulting command...$(...)
executes this command in a sub-shell, and is substituted with its standard output (which is empty here)favorite-browser
will simply openhttps://google.com/
(while the computer starts shutting down ifsudo
expects no password)In this PR, I propose to use
child_process.execFile(...)
as a safer replacement forexec(...)
. No shell involved, just a command name (favorite-browser
) and its unaltered string argument (the URL string, as-is).The drawback is that maybe someone somewhere has been successfully using something like
--defaultURLHandler "favorite-browser --some-browser-option"
, and this will not work anymore. IMHO, it's an acceptable trade-off. If you think it's not, then some alternative fixes could be:execFile(...)
: splitdefaultURLHandler
, use first word as command and remaining ones as additional arguments before the URLexec(...)
: properly shell-escape thedetails.url
string in the command (I think escaping$
as\$
, plus the double-quotes which has already been added around the string, might be enough, thanks to the limited set of chars we get in URLs, but not 100% sure)