Securing Git repository from accidental exposure using Chef

It was brought to my attention at the office that a few of our recently launched websites had publicly exposed .git repository information. Unscrupulous users could use the exposed data to pull down the entire commit history, giving them unfiltered access to what is basically the blueprint for the website.

What if someone accidentally uploaded a config file to the repository with sensitive information in it? Or what if the user was able to discover a major security vulnerability in the code that would have otherwise remained "safe"? Scary.

There is definitely too much risk in allowing public access to your .git directory.

I created a Chef recipe called
gitsec.rb to deploy a very easy and quick fix to 20 web servers.


# Apache
if File.exist? "/etc/init.d/httpd"
        directory "/etc/httpd/conf.d/" do
                owner "root"
                group "root"
                action :create
                recursive true
        end
        template "/etc/httpd/conf.d/gitsec.conf" do
               source "gitsec-apache.erb"
               owner  "root"
               group  "root"
               mode   "0644"
        end
        service "httpd" do 
                action :restart
        end
end
# Nginx
if File.exist? "/etc/init.d/nginx"
        directory "/etc/nginx/conf.d/" do
                owner "root"
                group "root"
                action :create
                recursive true
        end
        template "/etc/nginx/conf.d/gitsec.conf" do
               source "gitsec-nginx.erb"
               owner  "root"
               group  "root"
               mode   "0644"
        end
        service "nginx" do 
                action :restart
        end
end

I was not sure the best way to determine if a service exists using Chef, so I just check for the appropriate init script. All of our servers are RHEL or CentOS, so I do not do any detection of platform here. It would be trivial to do so, so I will leave that to you!

You will also want to create a couple of templates:

gitsec-apache.conf


## 
# Deny access to git/svn files by adding the following to httpd.conf
#
<Directorymatch "^/(.*/)*.git/">
    RewriteEngine on
    RewriteRule .* - [L,R=404]
</Directorymatch>

gitsec-nginx.conf


server {
    location ~ /.git {
        return 404;
    }
}

At first I was returning a 403 status code, but realized that it was still announcing that a file did exist at that location. 404 is better, it does not expose the existence of a file.

This recipe is part of my initial web server setup now.

Update

Really though, the web server should be configured to not allow access to any dot files...