Ask HN: How can I create a webserver that runs Git commands securely?

8 points by orhunp_ ↗ HN
Hi, I'm currently writing a webserver (REST API) which will run certain git commands such as "git clone" when a repository link is given via endpoint. I'm wondering how can I make this secure. There are a couple of security flaws that I could think of:

- cloning a huge repository will take a long time (how can I check the repository size?)

- cloning a couple of repositories at the same time might make the server slow

- running shell commands on the actual system might be dangerous

First thing I thought of was running these git commands in Docker. But I'm not sure that's applicable since everything will be running inside Docker anyways. What would be the best way of doing this?

9 comments

[ 3.4 ms ] story [ 31.1 ms ] thread
Look at https://nodered.org/ , many people use it for automating stuff.

The DIY version:

I'm sure there are better ways, but that's how I would do it:

> how can I check the repository size?

[1] https://stackoverflow.com/questions/8185276/find-size-of-git...

> cloning a couple of repositories at the same time might make the server slow

long running operations must run asynchronously. I would implement that as: client sends HTTP request to the server, server responds with a job ID and creates a temp directory with a random name containing information about the job (eg parameters). A scheduler (cron?) picks up the job, changes status, executes it. The scheduler can decide on parallelisation. The scheduler must run as a low-privileged user, possibly in a container as you suggested. The client needs to poll the server for job status.

> running shell commands on the actual system might be dangerous

The method described earlier partly mitigates that as the process doesn't run in the web server. I would create special job types (eg. one shell script for checking out, one for committing, one for pushing etc) and sanitise arguments (eg. no weird characters allowed). Running each job run in a sub directory of its own limits spill-over.

Look into using ‘sudo’. Sudo is not just for running things as root. It can also be used to allow a web service (Apache+PHP) to call a specific program (git) as a specific user (e.g. nobody).
You mean “su”?
sudo -u nobody git pull

That said, "nobody" will have its own challenges, like the lack of a $HOME meaning there is no git config file for the user, meaning you'll need to add a bunch of specific arguments to every git command. You might want to create a locked down user just for running git.

I heard that sudo due to PAM wasn't a means of dropping privileges.
Don't run web services as root.

Use net capabilities if you need tcp port bindings below 1024.

I'd also recommend running the git commands inside a forked process with another user in the same group (which has limited access to the filesystem). Alternatively use the git user/group and add the web service daemon user to the git group.

Also check that your linux distribution doesn't have binaries with the sticky flag set which could be used for privilege escalation. Double-check the list of gtfobins against your system's installed packages/binaries.

[1] https://gtfobins.github.com