To be clear (it wasn't mentioned explicitly in the blog post), but it's obviously what the author was referring to, this is about people who are deploying web sites with static content which is being managed via git.
And it only applies when the document root is also the git repo root. If the document root is under a subdirectory, the .git directory won't be served.
For simple static sites, I use a workflow very similar to this one[1]. It takes a minute or two to set up, but once it's all configured, you can deploy to your heart's content without ever worrying about exposing your .git directory to the world.
No. Not this. index.html has no business being in the root of your project.
Always, and I mean always put your web content into a directory separate from the root of your .git archive. This is the easiest way to avoid all of these problems.
Rails calls this directory "public", but it could be whatever you want, so long as what's mounted on your web server is not the root.
This isn't the best solution. Instead do as others have suggested and make a subdirectory of your project the webserver root.
This solutions just stops nginx (/whatever web server you're using) from displaying the file. If someone finds a remote-file inclusion vulnerability in your app, in all likelihood they can use said vulnerability to browse your .git directory -- because, hey, it's in your webserver directory, so the permissions are almost certainly set up so whatever user the webserver is running as (www-data probably/hopefully) can view it!
(Obviously if your webserver user can view important files such as these elsewhere on the system, you're still screwed -- but reducing attack surface, etc etc.)
OK, so I knew about this one before. But if you didn't, there's a better solution than just remembering it, which seems to be the gist of this post.
Solution: run one or more automated security tools across your sites, before deploying them to public locations. If possible, automate this process, so it happens all the time. The tools won't catch everything, but they will catch something you didn't, some of the time. Testing is good practice with all software! Do it.
I make it a habit to put all my public files in directory such as www/, where as .git and other non public but site-related files/directories are contained above this.
This is too much of blanket statement. As long as there's nothing secret in the repository, serving up .git is perfectly fine. Both http://codemirror.net and http://ternjs.net (projects by me) have websites that are simply checkouts of the projects' repositories. Which were already public.
This is pretty much a blanket statement for any project of reasonable size (or even with just a sole clueless developer). But don't take my word for it, check the evidence first hand by poking around the list for yourself :)
The solution is so effortless that it seems indefensible to serve .git, when the risk of doing so is a fleeting moment of forgetfulness leading to your site and databases getting pwned. Kind of like /etc/passwd being "public" so long as nobody puts their password in their GECOS field. Why take the risk.
I think there's nothing wrong with this if there aren't (and weren't) any secrets directly embedded in the source code and all configuration files that contain sensitive information are (and always were) properly gitignore'd.
Tech-savvy users can even be encouraged to pull the code and send patches. :)
Somebody correct me if I'm wrong here, but doesn't the .git directory essentially contain the entire history of the repository? The history could easily contain sensitive information like passwords. It will contain names email addresses of contributors, too. Try it yourself: cat .git/logs/HEAD
I'm running a (very small) personal site on lighttpd, and updating it via git. I checked my.server.com/.git/config - and was duly served the config file. Eek!
So I edited my /var/www/lighttpd/lighttpd.conf file, and added the following lines:
$HTTP["url"] =~ ".git" {
url.access-deny = ("")
}
and
(I have used [asterisk] for the symbol, here, as otherwise it rendered my text italic)
Instead of messing around with access and redirect stuff I would suggest, as others have in this thread, that you just put your files in a subdirectory and use this subdirectory as root for lighttpd.
Problem solved with two commands and you can also add additional stuff to your repository like sources before they went through different processors (coffee script, SASS,...) or various drafts. This way you also have a full copy of everything you need for your site in case something happens to your workstation.
.git should never be in your web root... I can't think of any situation (other than a very simple site) where you'd want to just stick the whole Git repository in the web root. Normally there's a bunch of other things in the repository (documentation, database scripts, etc.) that you wouldn't want exposed publicly.
If you use Apache, you can add the following to prevent the .svn directories from being served:
<LocationMatch ".\.svn.">
Order allow,deny
Deny from all
</LocationMatch
In a word: Rsync. What I do is have source files in one directory, filter them over to another with, at the moment, jinja2, then rsync that to my server using a shortcut script. The filtering is the tricky part.
devs aren't always the ones deploying the sites they develop! Also, non-standard file extensions for source code is often exposed and should probably be hidden. (e.g. .module for drupal sites).
[+] [-] tlongren|13 years ago|reply
FCC has a github account.
http://www.fcc.gov/.git/logs/HEAD
[+] [-] blaines|12 years ago|reply
[+] [-] camus|13 years ago|reply
[+] [-] tytso|13 years ago|reply
[+] [-] jstanley|13 years ago|reply
[+] [-] hdra|13 years ago|reply
[+] [-] peterjmag|13 years ago|reply
[1] http://toroid.org/ams/git-website-howto
[+] [-] astrodust|13 years ago|reply
Always, and I mean always put your web content into a directory separate from the root of your .git archive. This is the easiest way to avoid all of these problems.
Rails calls this directory "public", but it could be whatever you want, so long as what's mounted on your web server is not the root.
[+] [-] wldlyinaccurate|13 years ago|reply
[+] [-] fohlin|13 years ago|reply
[+] [-] hafabnew|12 years ago|reply
This solutions just stops nginx (/whatever web server you're using) from displaying the file. If someone finds a remote-file inclusion vulnerability in your app, in all likelihood they can use said vulnerability to browse your .git directory -- because, hey, it's in your webserver directory, so the permissions are almost certainly set up so whatever user the webserver is running as (www-data probably/hopefully) can view it!
(Obviously if your webserver user can view important files such as these elsewhere on the system, you're still screwed -- but reducing attack surface, etc etc.)
[+] [-] thejosh|13 years ago|reply
[+] [-] jaxbot|13 years ago|reply
[+] [-] contingencies|13 years ago|reply
Solution: run one or more automated security tools across your sites, before deploying them to public locations. If possible, automate this process, so it happens all the time. The tools won't catch everything, but they will catch something you didn't, some of the time. Testing is good practice with all software! Do it.
[+] [-] koyote|13 years ago|reply
[+] [-] alcat|13 years ago|reply
[+] [-] dan15|13 years ago|reply
[+] [-] drivebyacct2|12 years ago|reply
public_html has specific connotations for a reason.
[+] [-] marijn|13 years ago|reply
[+] [-] _wmd|13 years ago|reply
The solution is so effortless that it seems indefensible to serve .git, when the risk of doing so is a fleeting moment of forgetfulness leading to your site and databases getting pwned. Kind of like /etc/passwd being "public" so long as nobody puts their password in their GECOS field. Why take the risk.
[+] [-] drdaeman|13 years ago|reply
Tech-savvy users can even be encouraged to pull the code and send patches. :)
[+] [-] wldlyinaccurate|13 years ago|reply
[+] [-] scubbo|12 years ago|reply
I'm running a (very small) personal site on lighttpd, and updating it via git. I checked my.server.com/.git/config - and was duly served the config file. Eek!
So I edited my /var/www/lighttpd/lighttpd.conf file, and added the following lines: $HTTP["url"] =~ ".git" { url.access-deny = ("") }
and (I have used [asterisk] for the symbol, here, as otherwise it rendered my text italic)
$HTTP["host"] =~ "(.[asterisk])" { url.redirect = ( "^/.git(.*)" => "%1/nope.html" ) }
And restarted the server.
But my.server.com/.git/config still served up the config file. What am I missing?
[+] [-] dalore|12 years ago|reply
[+] [-] fallenhitokiri|12 years ago|reply
Problem solved with two commands and you can also add additional stuff to your repository like sources before they went through different processors (coffee script, SASS,...) or various drafts. This way you also have a full copy of everything you need for your site in case something happens to your workstation.
[+] [-] kl4m|12 years ago|reply
To explain it briefly:
[+] [-] dan15|13 years ago|reply
[+] [-] dsirijus|13 years ago|reply
[+] [-] kpommerenke|12 years ago|reply
If you use Apache, you can add the following to prevent the .svn directories from being served: <LocationMatch ".\.svn."> Order allow,deny Deny from all </LocationMatch
[+] [-] andyhmltn|13 years ago|reply
[+] [-] rlpb|13 years ago|reply
[+] [-] dougws|12 years ago|reply
[+] [-] coolj|12 years ago|reply
[+] [-] andrewflnr|12 years ago|reply
[+] [-] level09|12 years ago|reply
[+] [-] michaelmior|12 years ago|reply
[+] [-] johnbburg|13 years ago|reply
[+] [-] binarydreams|12 years ago|reply
[+] [-] unknown|12 years ago|reply
[deleted]