.htaccess prevents access to various files that are not supposed to be downloaded by users, including CVS's control files in the CVS directory: Entries, Root and Repository. In #28776: Protect svn files in .htaccess, the pattern was expanded to control files used by Subversion. I suggest this is extended to also cover files used by Git.
Unfortunately, we cannot use <DirectoryMatch> in .htaccess. The previous approach has been to include the names of files used by CVS and Subversion, but this isn't possible for Git, because the .git directory and its subdirectories may contain files with more or less any name.
I don't know whether the current list of filenames for CVS and Subversion is complete either (though #105851: finish hiding CVS/* files in .htaccess suggests that it is for CVS).
This patch suggests a new approach. If mod_rewrite is enabled, access to the complete directory is prohibited using a RewriteRule (credit). Otherwise, access to some of the known filenames is blocked using <FilesMatch>.
Comment | File | Size | Author |
---|---|---|---|
#51 | htaccess.patch | 2.2 KB | mfb |
#45 | htaccess.patch | 2.2 KB | mfb |
#43 | htaccess.patch | 2.19 KB | mfb |
#34 | htacess.patch | 921 bytes | droplet |
#30 | 581706-htaccess-30.patch | 748 bytes | Gribnif |
Comments
Comment #1
c960657 CreditAttribution: c960657 commentedComment #2
wretched sinner - saved by grace CreditAttribution: wretched sinner - saved by grace commentedIs it worth also expanding this for hg, bzr and any other common version control systems? Otherwise we will end up with a plethora of issues for these.
Comment #3
moshe weitzman CreditAttribution: moshe weitzman commentedSeems like a very good idea.
Comment #4
wretched sinner - saved by grace CreditAttribution: wretched sinner - saved by grace commentedbased on #3
Comment #5
c960657 CreditAttribution: c960657 commentedSeems like Mercurial uses a .hg directory, and Bazaar a .bzr directory, so that's pretty easy in the mod_rewrite case. I don't know whether it is possible to enumerate all possible file names in the directories, but the list of files easily gets very big.
Here is my suggestion: For CVS, we provide a complete list of filenames, while Subversion, Git, Mercurial and Bazaar are only protected by the mod_rewrite approach. CVS get this special treatment, because it is the VCS used by Drupal itself. This removes the special treatment that Subversion has gotten so far.
Also, in FilesMatch we block access to all files beginning with a period. This includes .cvsignore, .gitignore etc. as well as various temporary files created by CVS, Vim etc.
Comment #6
cburschkaMaybe this should just be generalized to all directories prefixed by a dot?
Comment #8
wretched sinner - saved by grace CreditAttribution: wretched sinner - saved by grace commentedTested and works as expected. Bumping priority as this will effect lots of people.
Comment #9
webchickHm. Is there a more generic way to handle this? Like excluding all files/directories that begin with a "."? This looks pretty dirty, and we'll need to keep maintaining it over time.
Also, critical is for "Drupal is actively dripping blood from its eyeballs." This doesn't remotely qualify. I don't think there's anything in these files that exposes anything security-wise, and even if so, people smart enough to use bzr/git/etc. can figure out their own re-write rules.
Comment #10
c960657 CreditAttribution: c960657 commentedThis blocks access to all directories whose names begin with a period.
AFAIK Git contains the complete source code in these directories. But I agree—this does not qualify as critical.
Comment #11
reglogge CreditAttribution: reglogge commentedCan confirm that this patch protects my .git directory which i deliberately placed in the webroot (big no-no under previous circumstances) when mod_rewrite is on. Same should be true for .hg, .svn, and .bzr since it's a generic rule protecting all directories beginning with a dot.
Files beginning with a dot are effectively protected by the FilesMatch directive.
Marking RTBC.
Comment #12
reglogge CreditAttribution: reglogge commentedsorry, RTBC'd too early, since I just read that two people have to sign off on a patch before RTBC-ing. Patch really works though :-)
Comment #13
moshe weitzman CreditAttribution: moshe weitzman commentedRTBC.
Comment #14
c960657 CreditAttribution: c960657 commentedReroll (due to #638030: Hide *.make files via .htaccess).
Comment #15
scor CreditAttribution: scor commented2 minor whitespaces issues
Comment #16
c960657 CreditAttribution: c960657 commentedFixed whitespace.
Comment #17
webchickGreat! Much better. :) Fixed up some of the language there (spell out 'version control system', add a missing word) and committed to HEAD.
Here's the patch I committed. Marking down for 6.x. Doesn't seem to apply cleanly, though.
Comment #18
arhak CreditAttribution: arhak commentedwhile at VCS, would .orig/.rej files worth be protected as well?
Comment #19
webchickWe can discuss that in a separate issue, but I kind of don't think so. It's one thing to protect against legitimate files that might be there if using certain deployment practices, but quite another to babysit people.
Comment #20
c960657 CreditAttribution: c960657 commentedComment #22
c960657 CreditAttribution: c960657 commented#20: vcs-htaccess-D6-1.patch queued for re-testing.
Comment #24
pfrenssenRerolled patch
Comment #26
wretched sinner - saved by grace CreditAttribution: wretched sinner - saved by grace commentedCommitted fix Feb 7: #581706 by c960657: Protect hidden directories (.git, .svn, etc.) in .htaccess.
Comment #27
scor CreditAttribution: scor commentedThis has not been committed to Drupal 6.x.
Comment #28
jlarky CreditAttribution: jlarky commentedMaybe this should just be generalized to all directories prefixed by a dot?
Because of this generalization i have some pages on my site blocked. Their names is started with dot, so i have 403 Forbidden on them. I figured out, that rule RewriteRule "(^|/)\." - [F] is wrong, because it have to check whether name is file/directory name or should be passed to drupal.
But anyway, I still dont know what to do with line
I think it will be more preferable write out every expected dot-whatever directory rather than simply ".*" like
it's includes files like .gitignore, so i think everything is under control :)
p.s. i'm using drupal 7, but as i can understand it's common bug, so i didn't start new issue for 7.0. Is it ok?
Comment #29
YesCT CreditAttribution: YesCT commentedI was wondering if blocking all things starting with a dot was too general also.
Comment #30
Gribnif CreditAttribution: Gribnif commentedBlocking all things starting with a dot is definitely too general, because:
I agree with the part of #28 which uses tests of "-f" and "-d" to ensure the thing being blocked exists in the filesystem first:
I am changing the version of this issue to 7.10, because the change is already live in D7, not in D6. The attached patch is for D7.
[Edit: I am withdrawing my patch. I incorrectly left out the modification to the long FilesMatch clause, and my patch would therefore not solve the problem. I now believe that the solution in #28 is the best course. It also applies cleanly to D8. I am resubmitting it for consideration with D8.]
Comment #32
jbrown CreditAttribution: jbrown commentedBugs are fixed in D8 then backported.
Comment #33
Gribnif CreditAttribution: Gribnif commented#28: vcs-htaccess-7.patch queued for re-testing.
Comment #34
droplet CreditAttribution: droplet commentedLeading .DOT in path should be working and let modules to use it. eg: #1661098: Autocomplete and words beginning with dot (.)
Attached a patch and tested:
- It blocked .git, .anything
- It allow example.com/.abc
Comment #35
forestmonster CreditAttribution: forestmonster commentedHunh. Stepping back for a moment, instead of blocking requests for individual files, it likely makes more security sense for us to create a whitelist of acceptable requests of Drupal; everything else would be ignored. That's because we can never cover all the bases in our FilesMatch rule (essentially our blacklist) of the files that an individual user, installing Drupal and then setting to work on their site, might leave littered around. We will always be playing catch-up.
It's true that creating and maintaining a whitelist is harder, since we have to overcome some habits: both Drupal core and contrib modules right now can arbitrarily create files, and will expect them to be delivered properly by the Web server software.
However we would have fewer habits to overcome, if modules could update this HTTP request whitelist upon creating a file.
Another option is user education, making sure that users know that any files placed in Drupal's docroot may be delivered by their Web server in response to any legitimate request.
Comment #36
boombatower CreditAttribution: boombatower commented@forestmonster: thanks for bringing a fresh perspective to this.
Whitelisting is generally a better security practice and given that it is also not proper use to just drop files in the drupal root (although I know people commonly do so) this seems like a logical direction to take. People can always whitelist there odd files if they really want to.
Comment #37
barraponto CreditAttribution: barraponto commentedThis will probably end the nasty "OMG, anyone can see Drupal's version by checking the CHANGELOG.txt security dripping blood from its eyes omg omg". As if we couldn't tell an opensource framework version by its CSS/JS.
Anyway, to get this rolling, we should whitelist:
* index.php
* core/install.php
* core/update.php
* sites/*/files/* (files, not dirs)
* robots.txt
* themes/modules css/js/img (other media?)
Comment #38
boombatower CreditAttribution: boombatower commentedNot sure how the redirect works with whitelisting since you can hit /install.php and it works fine. core/authorize.php?
Comment #39
forestmonster CreditAttribution: forestmonster commentedAnd a related discussion is going on at #1907704: Restrict temporary files created by text editors.
Comment #40
forestmonster CreditAttribution: forestmonster commentedAdded #1907934: Allowlist, instead of denylist, sensitive files and directories to handle these sorts of requests.
Comment #41
mjpa CreditAttribution: mjpa commentedIf you're going to whitelist sites/*/files/*, what happens when someone uses the UI to change where files are stored?
Comment #42
mfbDrupal should support RFC 5785, which establishes a .well-known URI location: https://tools.ietf.org/html/rfc5785
These URIs are registered with IANA - https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml - and include for example .well-known/openid-configuration as described at http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
So either .well-known needs to be whitelisted, or only specific hidden directories (.bzr .git .hg .svn etc.) should be blacklisted.
Comment #43
mfbUpdated patch at #34 to whitelist the .well-known path.
Comment #44
JvE CreditAttribution: JvE commentedI can't believe this has been sitting here like his since july 2012.
Droplets "tested" patch:
This is checking if the requested path is both a file AND a directory at the same time and thus will never block anything.
Comment #45
mfbOK I added the [OR] flag to fix that..
Comment #46
mfbComment #48
mfb45: htaccess.patch queued for re-testing.
Comment #49
jhedstromComment #51
mfbrerolled
Comment #52
tim.plunkettComment #54
mfbI'd really like to add support for the .well-known directory to D7 so I created #2408321: Support RFC 5785 by whitelisting the .well-known directory in hopes of getting this part of the patch in faster.
Comment #55
Mile23Using Drupal 8.0.x I tried to access
http://localhost:8888/.git
and.hg
and.bzr
.In all cases I got something this:
So therefore I'm calling this issue CWF. Please re-open if this is in error.
There's also some overlap with #2408321: Support RFC 5785 by whitelisting the .well-known directory