There is a minor security issue where this configuration file could potentially have been previously customized with private information (e.g. the location/configuration of password protected directories, internal proxy configuration etc).

If the site was then moved to Apache based hosting then this information is now visible (e.g. http://www.d8sites.org/web.config).

This is particularly an issue if the rules were not re-implemented in the Apache .htaccess file meaning (for example) a password protected directory is now both unprotected and easily discovered. Obviously the first of these is a serious issue on it's own, but I don't think that is a reason not to prevent the latter.

For the same reasons .htaccess should probably also be blocked in web.config.

Comments

DKAN created an issue. See original summary.

dkan’s picture

Title: Hide web.config in .htaccess (and vice-versa) » Block web.config in .htaccess (and vice-versa)
chi’s picture

Version: 9.x-dev » 8.6.x-dev
Category: Bug report » Task
Status: Active » Needs review
StatusFileSize
new782 bytes

This makes sense for me.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

interx’s picture

Status: Needs review » Reviewed & tested by the community

The patch works well.

As mentioned, if you have a modified web.config from a previous hosting environment, there might be a potential security issue.
But even if you use an unmodified version it still makes sense to disallow access. On multiple occasions a security audit on a Drupal site mentioned the public access to web.config. Even though it was explicitly mentioned that it was the vanilla version in use, access had to be blocked anyhow. This patch does just that on Apache.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

This is only doing half of the fix suggested in the issue summary - blocking web.config from .htaccess. It's not blocking .htaccess from web.config - not that I'm sure that that is necessary because it is a hidden file - but I don't know how IIS works. Also I think we should block web.config in the root directory specifically - not all .config files. Plus this is testable in \Drupal\Tests\system\Functional\System\HtaccessTest

greggles’s picture

Status: Needs work » Needs review
StatusFileSize
new2.18 KB

Here's an untested patch that:
* adds blocking for .htaccess from web.config
* adds a test for the htaccess change

@alexpott can you clarify how common you think it is for sites to want to allow downloading a .config file? It seems to me like a sufficiently obscure use case that it would be OK to block by default.

@interX could you review/test again on both apache and iis?

Status: Needs review » Needs work
greggles’s picture

The fail was in the test I added, so indeed that needs work.

1) Drupal\Tests\system\Functional\System\HtaccessTest::testFileAccess
The file core/modules/system/tests/fixtures/HtaccessTest/access_test.config exists.
Failed asserting that false is true.

alexpott’s picture

@greggles I guess it is super uncommon - but if someone has a site sharing .config files for different .NET configurations then they'd suddenly stop working no?

greggles’s picture

We already block config files in yml so while I agree it could be disruptive it seems like a small price to pay in exchange for the extra security.

alexpott’s picture

@greggles sure but why not add |web\.config after composer\.(json|lock)

chi’s picture

I agree web\.config will make the intention more clear.

interx’s picture

The last patch still works for me.

It is possible that web.config includes other .config files with an arbitrary name.

So I think it's a good idea to simply block all .config files, not just web.config. There might be some impact, although this should really be exceptional.

It is safer by default, these are configuration files after all. Like YML-files, if you would want to, you can still allow them to be served by explicitly overriding the rule in your vhost, folder, ...

longwave’s picture

Status: Needs work » Needs review
StatusFileSize
new2.65 KB
new2.9 KB

This patch explicitly blocks web.config and .htaccess from web.config itself, and also should fix the tests.

I did also notice that the regexes differ elsewhere in a few places - web.config blocks code-style.pl (not sure why) and what looks like SVN repository files, but not .make files - we should probably open another issue to unify this properly. Both files also block .xtmpl files, which are surely long obsolete.

mcdruid’s picture

alexpott’s picture

I feel that what we're doing here is putting a plaster on a wet leg and really we should be recommending https://www.drupal.org/node/2767907 and in fact deprecating our let's serve all the code because why not pattern.

But +1 to better protection for now.

beckydev’s picture

Tested @longwave's patch in #15 in an Apache environment and can confirm web.config is no longer served up.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

sammuell’s picture

The pentest tool Nessus Pro regards the presence of a web.config file as a medium threat (web.config File Information Disclosure).

The amount of disclosed information is negligible because Drupal is oss anyway, unless the file has been altered manually. Nontheless, it would be good practice to block access to the file.

Synopsis
The remote web server hosts an application that is affected by an information disclosure vulnerability.

Description
An information disclosure vulnerability exists in the remote web server due to the disclosure of the web.config file. An unauthenticated, remote attacker can exploit this, via a simple GET request, to disclose potentially sensitive configuration information.

Solution
Ensure proper restrictions are in place, or remove the file if the file is not required.

beckydev’s picture

To echo @sammuell, this has also been flagged in my workplace by Qualys' scanner.

greggles’s picture

Priority: Minor » Normal

Bumping priority as this does feel at least normal to me.

To folks advocating for this issue - please download the patch, apply it, test it out, confirm it works well for you, test it out in various environments. That will help push it along the most at this point.

mcdruid’s picture

I manually tested the patch on both webservers.

Apache before:

$ curl -sLIXGET drupal8x.xp/web.config
HTTP/1.1 200 OK
Date: Thu, 11 Apr 2019 09:00:41 GMT
Server: Apache/2.4.18 (Ubuntu)
X-Content-Type-Options: nosniff
Last-Modified: Thu, 11 Apr 2019 09:00:39 GMT
Accept-Ranges: bytes
Content-Length: 4555
Cache-Control: max-age=1209600
Expires: Thu, 25 Apr 2019 09:00:41 GMT

...and after:

$ curl -sLIXGET drupal8x.xp/web.config
HTTP/1.1 403 Forbidden
Date: Thu, 11 Apr 2019 09:00:33 GMT
Server: Apache/2.4.18 (Ubuntu)
X-Content-Type-Options: nosniff
Content-Length: 296
Content-Type: text/html; charset=iso-8859-1

IIS before:

$ curl -si drupal.win/.htaccess
HTTP/1.1 404 Not Found
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 11 Apr 2019 11:00:52 GMT
Content-Length: 1245

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>404 - File or directory not found.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} 
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>404 - File or directory not found.</h2>
  <h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
 </fieldset></div>
</div>
</body>
</html>

...and after:

$ curl -si drupal.win/.htaccess
HTTP/1.1 403 Forbidden
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 11 Apr 2019 11:03:42 GMT
Content-Length: 1233

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>403 - Forbidden: Access is denied.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} 
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>403 - Forbidden: Access is denied.</h2>
  <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>
 </fieldset></div>
</div>
</body>
</html>

I know very little about IIS but it looks like it won't serve out .htaccess by default - AFAICS requests for any "dotfile" without a file extension result in a 404.

With the patch we get a 403 instead though, which makes sense.

This is an older version of IIS on a VM I had lying around, so perhaps someone with a more up-to-date environment and more knowledge of IIS could confirm.

mcdruid’s picture

rabbitlair’s picture

StatusFileSize
new2.29 KB

I think the patch from #15 can be improved with a couple of minor details:
- The file mode changes for the files core/modules/system/tests/fixtures/HtaccessTest/.htaccess and core/modules/system/tests/fixtures/HtaccessTest/web.config may be not needed
- There is a missing slash to escape the dot character on the web.config file name from the Match directive on web.config file (it should be web\.config instead of web.config)

This patch fixes both details.

Status: Needs review » Needs work

The last submitted patch, 25: 2948579-25-block_web_config_htaccess.patch, failed testing. View results

mcdruid’s picture

Status: Needs work » Needs review
StatusFileSize
new2.65 KB
new871 bytes

I think those "file mode changes" are actually new 0-byte files which are required for the test.

This patch puts those back in, but adds the slash in to web\.config as per the last comment by @rabbitlair

greggles’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/web.config
@@ -22,7 +22,7 @@
-          <match url="\.(engine|inc|install|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format|composer\.(json|lock))$" />
+          <match url="\.(engine|inc|install|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format|composer\.(json|lock)|\.htaccess|web\.config)$" />

Why does this block web.config as well? I would have thought that IIS has this covered - no?

Our .htaccess file should block web.config files and our web.config file should block .htaccess (maybe - personally I have nfi what IIS does with files starting with a . - seems okay to be explicit though). But I can't see a reason why our web.config should be responsible for web.config security on IIS.

greggles’s picture

Status: Needs work » Needs review
StatusFileSize
new2.64 KB

Thanks for the feedback, @alexpott. This should be the same as #27 but without blocking web.config in the web.config.

mcdruid’s picture

(edit: I cross-posted with @greggles so I've removed my patches which are likely identical - hopefully the notes about my testing etc... are still of some use though)

Fair enough - you could argue a belt-and-braces approach to try and prevent mis-configured webservers serving out "their own" config file, but in that case we'd want to be consistent and block both files within both files.

Here's the patch with web.config removed from the web.config file.

I tested this in a newer version of IIS (IIS 10 on Windows Server 2016) on an Azure VM (took a while to figure out that I needed the URL rewrite module and how to obtain and install that... but I digress).

I can confirm that a request for .htaccess yields a 403 with the new rule in place.

Requesting web.config itself produced an informative page including the following details:

HTTP Error 404.8 - Not Found

The request filtering module is configured to deny a path in the URL that contains a hiddenSegment section.

Detailed Error Information:

Module
RequestFilteringModule

Notification
BeginRequest

Handler
StaticFile

Error Code
0x00000000

Requested URL
http://localhost:80/web.config

Physical Path
C:\inetpub\wwwroot\web.config

More Information:
This is a security feature. Do not change this feature unless the scope of the change is fully understood. If content should be served from a specific directory being denied by this setting, remove the denied directory from configuration/system.webServer/security/requestFiltering/hiddenSegments.

So I take this to mean that denying this request is default behaviour in IIS, and that it may be possible to change this behaviour.

The same's typically true for apache and .htaccess as that behaviour is determined by a few lines in the config file e.g.

#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^\.ht">
        Require all denied
</FilesMatch>

So unless we want to be extra-paranoid and try to prevent (mis-)configuration of these webservers granting access to their own config files, I think this patch achieves what we set out to do in this issue, and no more.

Back to RTBC (if tests pass).

I'll make the same change in the D7 port issue/patch.

mcdruid’s picture

Status: Needs review » Reviewed & tested by the community

Tests did pass; so back to RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Crediting @DKAN for filing the issue.
Crediting myself, @interX, @beckydev, and @sammuell for issue comments that have helped to move the patch along.

Committed dfa4cde and pushed to 8.8.x. Thanks!

This improvement will ship in 8.8.0 - so in 6 months time but this is not eligible for backport to 8.7.x because it is a task and not a bug.

  • alexpott committed dfa4cde on 8.8.x
    Issue #2948579 by greggles, mcdruid, longwave, Chi, rabbitlair, alexpott...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.