gitserver: Only allow acceptable commands and POST method in /exec
Created by: indradhanush
Patch for https://github.com/sourcegraph/security-issues/issues/213.
Note to reviewers
This PR also fixes an edge case with the isAllowedGitCmd
function. So it's suggested to look at the commits one after the other during review as this function and related functions and variables have also been moved from internal/vcs/git
to internal/gitserver/gitdomain
.
Without this move, golangci-lint
caught a cyclic dependency between cmd/gitserver/server
and internal/vcs/git
:
-
internal/vcs/git/main_test.go
already importscmd/gitserver/server
-
cmd/gitserver/server/server.go
would now be importinginternal/vcs/git
if we didn't moveIsAllowedGitCmd
tointernal/gitserver/gitdomain
package.
Regression concerns
On scanning the PR commit by commit, reviewers should also notice the addition of multiple new commands to the allow list. This does not introduce new behavior, but adds the existing set of commands which are already in use in the /exec
endpoint. With the check for the allow list in in func (s *Server) exec
, existing tests were failing unless these commands and in some cases extra args were added to the allow list. My concern here is that if we have existing commands in use for which test cases do not exist, this PR could lead to a severe regression.
My thoughts at this point are to keep the code around the allow list checking guarded behind a feature flag while at the same time doing a dry run check and logging any commands that fail the check for the next few days. Observing the logs in production should give us a concrete list of commands that are not present in the allow list at the moment. I'd appreciate any thoughts or suggestions on the best path to take forward.
Update
The PR now does the following in order to avoid regressions:
- Increment the prometheus metric
src_gitserver_exec_blocked_command_received
if a blocked command is received by gitserver's/exec
endpoint - Always log blocked commands as a warning
- If the feature flag
experimentalFeatures.enableGitServerCommandExecFilter
is set totrue
, block the command from being executed or else default to current behavior of letting the command be executed
Note: By default the feature flag is disabled and merging this PR WILL NOT fix the linked issue.
Test Plan
- Merge the PR and deploy to cloud
- Monitor the new metric
src_gitserver_exec_blocked_command_received
for 2-3 days - If the metric has a non-zero value after this initial monitoring period, inspect logs to identify commands that are logged as blocked commands
- Depending on the command update the allow list
- GOTO 1 until the metric's value is
0
(Note: Userate
orincrease
as this is a monotonically increasing counter)
Tagging @sourcegraph/security for suggestions on testing plan and timeline with respect to SLA.