110

I have started using git for deployment of websites for testing. How do I prevent apache from serving the .git directory contents?

I tried

<Directorymatch "^/.*/\.svn/">
Order deny,allow
Deny from all
</Directorymatch>

with no success.

I know that I can create a .htaccess file in each .git directory and deny access, but I wanted something I could put into the main config file that makes this global across all websites.

Shoan
  • 1,715
  • 5
  • 17
  • 23
  • 3
    Once you've prevented apache from serving the directory you may also need to hide the .git directory with "IndexIgnore .git" if you have Indexes enabled on your directory. – Ryan Jul 21 '15 at 18:17
  • 1
    Hey, consider changing the accepted answer. Bennett's seems more appropriate. Thanks. – Gray Aug 07 '23 at 21:00

12 Answers12

196

This has the same effect as many of the other answers but is much simpler:

RedirectMatch 404 /\.git

This can go into .htaccess or your server config file. It hides any file or directory whose name begins with .git (e.g. a .git directory or .gitignore file) by returning a 404. So not only are the contents of your Git repo hidden, its very existence is hidden too.

Bennett McElwee
  • 2,076
  • 2
  • 15
  • 9
  • 4
    I really like this solution. It's simple and elegant. – Shoan Mar 08 '14 at 09:02
  • 5
    Putting this in the root htdocs directory does a global job, too. – jor Feb 27 '15 at 14:19
  • This answer is awesome. Simple. Clean. And works even when DirectoryMatch doesn't. – Jake May 01 '15 at 16:41
  • 6
    Love this option the best as well. Seems to me that it is more secure to return a 404 for requests like /.git or /.gitignore so that the fact that git is even being used can't be determined from the outside. – Ezra Free Sep 06 '15 at 02:54
  • 2
    Be aware that with if you have directory listings enabled, the `.git` folders will still be visible, but you'll get the 404 when you try to access them. – Andy Madge Feb 04 '16 at 15:21
  • @AndyMadge Excellent point. Directory listings are a pretty blunt instrument though; if you are concerned about details like concealing the existence of certain directories, you should not have directory listings enabled. – Bennett McElwee Feb 04 '16 at 20:54
  • 1
    @BennettMcElwee yep agreed, there's almost never a good reason to have directory listing enabled globally on a production server. Just thought it deserved a mention in case it catches someone out. – Andy Madge Feb 04 '16 at 21:01
  • How would I do it globally because my apache serves 100s of projects which runs either using Virtual Hosting or Directly with IPs. Is their a way to configure at only one place ..? – shashwat Jun 13 '16 at 13:57
  • 1
    Is it recursive? for example, can we access `.git/config` after we add this rule? – shashwat Oct 31 '17 at 11:44
  • 2
    @shashwat you can't access the .git directory or anything in it, including .git/config. All such attempts will give a 404 error. – Bennett McElwee Oct 31 '17 at 22:46
  • If you omit the leading slash '/' then this solution blocks access to `.git` directories everywhere under the document root, not just _in_ the document root: `RedirectMatch 404 \.git` . – András Aszódi Jul 02 '20 at 07:21
  • 1
    @LaryxDecidua This solution does that anyway. No need to omit the leading slash. If you omit it then it will also block files with names like `smoke.gitanes`, which is probably not what you intended. – Bennett McElwee Jul 02 '20 at 11:22
  • Or just `RedirectMatch 404 /\.` to block all files/folders starting with '.' – ColinM Jul 31 '22 at 05:48
81

It's not working because you have 'svn' instead of 'git' in the rule. All you have to do is to replace the 'svn' with 'git'.

<Directorymatch "^/.*/\.git/">
  Order 'deny,allow'
  Deny from all
</Directorymatch>
Manuel
  • 3
  • 2
sinping
  • 2,070
  • 14
  • 13
  • 2
    When I create a .htaccess containing only your code, I get the error: " – Shoan Jul 27 '10 at 19:03
  • 2
    It has to be in the Apache conf. See: http://httpd.apache.org/docs/1.3/mod/core.html#directorymatch – sinping Jul 28 '10 at 12:45
  • 4
    The simplest regex is `` – Bachsau Apr 05 '17 at 18:00
  • Check this for perfect solution https://magento.stackexchange.com/questions/202840/how-to-secure-magento-version-control-systems – Pratik Kamani Nov 23 '17 at 05:25
  • 1
    1st, thanks to singping/OP. Note that in Apache 2.4 the "Order,deny" and next line have been replaced by "Require all denied". Also, many installations the file called "Apache conf" above is named "httpd.conf" --- singping's usage was just a casual statement, so don't search for that literal name (should probably go without saying, but you never know how people might read it). – Kevin_Kinsey Sep 14 '18 at 21:44
  • Remember to add the above block in your or apache .conf file (apache2.conf or httpd.conf, etc). But it works. :) – Ricardo Martins May 01 '19 at 22:35
  • While this answers the question, you could simplify the regex and make it apply for any .git directory on any level. Simplified regex already suggested by @Bachsau – Sybille Peters Jun 02 '20 at 13:32
18

If you're on a shared hosting service and don't have access to apache.conf, you can still do it in your .htaccess file, like this:

RewriteEngine On
RewriteRule "^(.*/)?\.git/" - [F,L]
danorton
  • 735
  • 1
  • 8
  • 26
15

If you don't use .htaccess files but instead want to use /etc/apache2/httpd.conf (or whatever your server's master conf file is) to hide both .git directories and .gitignore files, you can use the following. I found the answer above for master conf setting did not hide the gitignore file.

# do not allow .git version control files to be issued
<Directorymatch "^/.*/\.git+/">
  Order deny,allow
  Deny from all
</Directorymatch>
<Files ~ "^\.git">
    Order allow,deny
    Deny from all 
</Files>
Kyle Sloan
  • 159
  • 1
  • 2
8
### never deliver .git folders, .gitIgnore
RewriteRule ^(.*/)?\.git+ - [R=404,L]

# 2nd line of defense (if no mod_rewrite)
RedirectMatch 404 ^(.*/)?\.git+

This works in .htaccess, no http.conf access required. Include this as the first of rewrite rules. Prepend Rewrite On if needed.

From a security angle, I prefer a bogus 404 over an 403, more informative to the attacker. Comment one of the two out, to ensure, the other works for you, too.

Btw, good changes are, your lithmus test for the two are:

http://localhost/.gitignore
http://localhost/.git/HEAD
Frank N
  • 600
  • 8
  • 18
  • Why have both rules? The simpler RedirectMatch suffices on its own. (Also, the regexes don't seem quite right -- why the plus on the end?) – Bennett McElwee Aug 01 '13 at 10:20
  • Personal Paranoia / doubled security. If RewriteEngine happens to get turned off (central config changes, poor team communication, unlucky server "update",... you name it :-) The + is obsolete or should be a $, good point! (no time for testing, sorry.) – Frank N Aug 02 '13 at 12:24
  • If you're worried that RewriteEngine might be off, just put `RewriteEngine On` before your RewriteRule. But anyhow it is tautological and redundant because the simpler RedirectMatch suffices on its own. Though even that could be simplified. Basically I am recommending [my answer](http://serverfault.com/a/527911/57883) instead. :) – Bennett McElwee Aug 03 '13 at 04:51
  • +1 for the litmus test. –  Jul 15 '14 at 14:58
  • Why a `+` at the end of the rewrite rule? Wouldn't that mean one or more instances of the letter `t`? Doesn't make sense to me, but this answer isn't the only place I've seen this exact wording of that RewriteRule; hoping you can clarify. – Wildcard Aug 25 '23 at 00:38
6

To protect both the .git directory as well as other files such as .gitignore and .gitmodules using .htaccess, use:

RewriteEngine On
RewriteRule ^(.*/)?\.git+ - [F,L]
ErrorDocument 403 "Access Forbidden"
scribu
  • 337
  • 1
  • 5
  • 10
  • 4
    Does work for me, however the trailing ErrorDocument has no impact. From a security angle, I'd fancy a bogus 404 over an informative 403 to the attacker... – Frank N May 26 '13 at 10:01
  • 2
    This is a bad idea, because it discloses information to hackers. A 403 means it's there, a 404 means it's not. Every fact on a server's setup is usefull to a hacker. I'd consider revising this. – GerardJP Dec 10 '14 at 10:25
4

I always add the following line into vhost template

RedirectMatch 404 /\\.(svn|git|hg|bzr|cvs)(/|$)

Just to be sure that no one can access VCS specific data. Works perfect.

ALex_hha
  • 7,193
  • 1
  • 25
  • 40
2

Assuming your webserver is using a different user than the one you use to access the .git repository, you could disable the execute bit for others on the .git directory.

This should work with other webservers and doesn't rely on performance-consuming .htaccess files.

Martijn
  • 356
  • 5
  • 13
2

For those looking to simply deny all "hidden" files and directories on a Linux distribution (generally all files beginning with a "."), here's what works on Apache 2.4 when placed in server conf context:

<FilesMatch "^\.(.*)$">
    Require all denied
</FilesMatch>
<DirectoryMatch "/\.(.*)">
    Require all denied
</DirectoryMatch>

And here's the older Apache 2.2 style (same regex, just different auth directives):

<FilesMatch "^\.(.*)$">
    Order deny,allow
    Deny from all
</FilesMatch>
<DirectoryMatch "/\.(.*)">
    Order deny,allow
    Deny from all
</DirectoryMatch>

Then you don't have to worry about .git or .svn specifically. That would also match things like .htaccess and .htpasswd inherently.

Personally, I like issuing 403s for such requests instead of 404s, but you could easily use a RewriteRule instead of auth denial, like so:

<FilesMatch "^\.(.*)$">
    RewriteRule "^(.*)$" - [R=404,L]
</FilesMatch>
<DirectoryMatch "/\.(.*)">
    RewriteRule "^(.*)$" - [R=404,L]
</DirectoryMatch>
ldennison
  • 163
  • 1
  • 7
1

This is a little late but my answer is a slightly different so I thought I would add it. This must go in the httpd.conf file. The <Files "*"> nested inside the <Directory> tag will block all files in the directory.

# GitHub Directory
<Directory /var/www/html/yoursite/.git>
   Order Deny,Allow
   Deny from all
   <Files "*">
     Order Deny,Allow
     Deny from all
   </Files>
</Directory>
# GitHub files
<Files .gitignore>
  order Deny,Allow
  Deny from all
</Files>
I'm Root James
  • 212
  • 3
  • 13
0

Ubuntu's apache2 package has a security.conf file that suggests

<DirectoryMatch "/\.svn">
   Require all denied
</DirectoryMatch>

(or change .svn to .git to block access to git, or use both )

Guss
  • 2,670
  • 5
  • 34
  • 59
0

You probably want to deny serving .gitignore as well.

Files starting with a dot are hidden in linux.

Therefore, just 404 anything that begins with a dot:

RedirectMatch 404 /\.

Val Kornea
  • 186
  • 6