Securing Web Servers

This document came about as part of our development project 287 to come up with strategies and practical configuration to harden web servers against compromise. Some of the suggestions/guidance are generic, but some contain concrete examples/steps that are applicable to our DICE managed environment, and are tagged with DICE in that case, in which case it will probably assume you are using the dice/options/apacheconf.h header to configure your apache.

It is currently a work in progress, and new sections will be added as work is completed.

Currently in no particular order

Reduce HTTP server identity strings

Rather than announcing which version of apache or whatever you are using to the outside world (this information is usually included in the HTTP response headers), you may want to consider removing or reducing the amount of information you volunteer. Thus making it a bit trickier for a would be attacker to target their tools on any version specific issues with the software you are using.

DICE

Profiles using the apacheconf.h will have:

!apacheconf.servertokens mSET(Minor)
and profiles including apacheconf-php5.h have the following configuration to turn off the exposure of PHP.
!apacheconf.verbatim                mADD(phpexpose)
apacheconf.verbatimline_phpexpose   php_admin_value expose_php off

Limit the number of concurrent connections from a single IP

As basic protection from a DoS (accidental or malicious) attack, use a module like mod_limitipconn.

DICE

We have a dice/options/apacheconf-iplimit.h header which sets a site wide limit of 30 simultaneous connections from a single IP address. That can be overridden by #define DICE_OPTIONS_APACHECONF_IPLIMIT_DEFAULT 10 before including the header, for example.

The header also attempts to log denied connections to /var/lcfg/log/apacheconf.ipdenied though whether this will actually work depends on how apache logging is configured on your site.

Obviously after adding the header, you can do more specific limiting as documented in the limitip README.

Deny framing

To stop other sites from including your site within an HTML Frame, and thus possibly capture any sensitive data entered into forms on your site, you can have apache set an HTTP response header of "X-Frame-Options: DENY", which will tell the browser not to render your site within any frame. However there are other options SAMEORIGIN and ALLOW-FROM . See https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options

DICE

Adding the header dice/options/apacheconf-denyframe.h will set this header to simply DENY. This can break some legitimate things, eg the Plone edit page, as the editor uses a IFRAME, or Drupal uploads. In which case you probably want to use the the SAMEORIGIN option. This can be overridden by

#define DICE_OPTIONS_APACHECONF_DENYFRAME_OPTION   SAMEORIGIN
Before including the apacheconf-denyframe.h header.

Disable the HTTP Trace method

Like GET and POST there is TRACE method in the HTTP spec. It has been shown that this can potentially be exploited to reveal data to Javascript that would otherwise be denied, particularly cookie data - see https://www.owasp.org/index.php/Test_HTTP_Methods_%28OTG-CONFIG-006%29 .

In apache, the TRACE method can be disabled via the directive TraceEnable off.

DICE

The dice/options/apacheconf-notrace.h will turn off the TRACE method.

Use mod_security

The mod_security apache module comes with various default rules to deny some suspicious activities. However it can be a bit over zealous, and we've had problems with it wrongly denying uploads via web forms. So you should review its default configuration.

DICE

The header dice/options/apacheconf-security.h adds mod_security and currently has some extra rules to protect against the Shellsock exploit from September 2014. There are also some #defines that you can specify to avoid some of the common false positives, particularily if your web site supports uploads of some form.

DICE_OPTIONS_APACHECONF_SECURITY_ALLOWHYPHENS skips the rule that sometimes causes problems with web form uploads. It seems to be something to do with the mime-type boundary and the string "--" within the data submitted by the form. Setting this define removes this check.

DICE_OPTIONS_APACHECONF_SECURITY_BODYLIMIT Configures the maximum request body size ModSecurity will accept for buffering, including the size of any files being transported in the request (in bytes). This should be set to at least the maximum upload size of any web forms your site supports. It defaults to about 13MB if you don't specifying anything.

DICE_OPTIONS_APACHECONF_SECURITY_BODYNOFILESLIMIT Configures the maximum request body size ModSecurity will accept for buffering, excluding the size of any files being transported in the request. The default is 128KB

DICE_OPTIONS_APACHECONF_SECURITY_BODYINMEMORYLIMIT Configures the maximum request body size that ModSecurity will store in memory. Default is 128KB.

If these limits are too low, apache will report an 413 (Request Entity Too Large) error.

See the directives starting at https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#secrequestbodyinmemorylimit for more details.

Think about CosignRequireFactor

If you are using Cosign to authenticate people on your web site/service, are you using an appropriate CosignRequireFactor directive to potentially limit those who can authenticate to your site?

DICE

As both DICE users and iFriends can authenticate against our Cosign Service, then without a restriction in place, potentially anyone in the world can authenticate against a Cosign protected site/service. If you want to limit authentication to just DICE users, then you should set the apache directive CosignRequireFactor INF.ED.AC.UK. This will be the default for the main apache config if you use the dice/options/apacheconf-cosign.h header.

If you want to override this, eg then you can #define DICE_OPTIONS_COSIGN_FACTORS prior to including the header. Or can an specify a later CosignRequireFactor in the apache config, and it will override any previous settings, even if the given argument is the empty string.

If you are using EASE Cosign rather than DICE, then you'll probably want to set the factor to EASE.ED.AC.UK.

Note that value set in the main apache config for CosignRequireFactor is not cascaded down to any VirtualHost definitions. So you should explicitly set the require factor directive in those, or anyone will be able to authenticate.

-- NeilBrown - 31 Mar 2014

Topic revision: r11 - 26 Jun 2015 - 14:58:29 - NeilBrown
 
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback
This Wiki uses Cookies