Improper Input Validation in filebrowser/filebrowserValid
Oct 1st 2021
File Browser is a web-interface that allows you to manage and navigate through your files in a web browser.
One of its features is to allow a user to run specific shell commands in the server, these commands are specified by users with administrator privileges, with an allow list.
This feature is implemented on the frontend side with a web shell using web sockets and the enforcement of the allow list is made on the backend, by spliting the user input by spaces, to obtain the commands and arguments, and then checking the command (first substring) against the list of allowed commands.
The allowed commands are interpreted as a regex and matched against our first substring. This feature is not clearly stated in the documentation. Therefore, if a user follow your example (
A space separated list with the available commands for this user. Example: git svn hg.), an attacker that sends something like
aaaaagit, would pass the regex check, because it has the substring
After these checks, the original user input is splitted again inside the function
runner.ParseCommand by calling the function
caddy.SplitCommandAndArgs(Source). This last function uses a more complex way to divide commands and args, that considers in addition to spaces, more characters like tabsSource and a state machine that ignores comments. Finally, the parsed command is passed to
These two facts allow an attacker to have arbitrary command injection, if he has an account with the permission to run a specific command.
A payload to explore this vulnerability would be a command that uses tabs instead of spaces and has the allowed command inside a comment. This would pass the security checks, because in the first split, with
strings.Split, the command is interpreted as a command without args that matches the regex, and then the
caddy.SplitCommandAndArgs correctly parses the user input, identifying commands and arguments, and ignores the comment.
Proof of Concept
This PoC assumes that you have an user account that can only run the
- Login with the user account
- Click on toggle shell
- Write the following command:
Note that between the
#git, there is a tab character and not a space.
A user can run unintended commands in the machine hosting the web server with the permissions of the web application. This can compromise the server and the users' files.
Instead of splitting the user input with
strings.Split, use the function
caddy.SplitCommandAndArgs to enforce that we are checking the allow list against the command that will be used in the
exec.Command. And in addition to that, also evaluate whether interpreting the command as a regex is really necessary and, if yes, inform the user properly.