Category Archives: Apache

Disable Unnecessary Modules in Apache

Objective

To disable unneeded Apache modules in order to reduce the memory utilized and improve performance. This may also result into improved security since it is a best security practice to not enable things you do not need.

Solution

First, take a look at what modules your Apache install currently loads on Apache startup. You can view a list of enabled modules by typing the following from shell:

[root@nowherelan]# httpd -M
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 access_compat_module (shared)
 actions_module (shared)
 alias_module (shared)
 allowmethods_module (shared)
 auth_basic_module (shared)
 auth_digest_module (shared)
 authn_anon_module (shared)
 authn_core_module (shared)
 authn_dbd_module (shared)
 authn_dbm_module (shared)
 authn_file_module (shared)
 authn_socache_module (shared)
 authz_core_module (shared)
 authz_dbd_module (shared)
 authz_dbm_module (shared)
 authz_groupfile_module (shared)
 authz_host_module (shared)
 authz_owner_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 cache_module (shared)
 cache_disk_module (shared)
 data_module (shared)
 dbd_module (shared)
 deflate_module (shared)
 dir_module (shared)
 dumpio_module (shared)
 echo_module (shared)
 env_module (shared)
 expires_module (shared)
 ext_filter_module (shared)
 filter_module (shared)
 headers_module (shared)
 include_module (shared)
 info_module (shared)
 log_config_module (shared)
 logio_module (shared)
 mime_magic_module (shared)
 mime_module (shared)
 negotiation_module (shared)
 remoteip_module (shared)
 reqtimeout_module (shared)
 rewrite_module (shared)
 setenvif_module (shared)
 slotmem_plain_module (shared)
 slotmem_shm_module (shared)
 socache_dbm_module (shared)
 socache_memcache_module (shared)
 socache_shmcb_module (shared)
 status_module (shared)
 substitute_module (shared)
 suexec_module (shared)
 unique_id_module (shared)
 unixd_module (shared)
 userdir_module (shared)
 version_module (shared)
 vhost_alias_module (shared)
 dav_module (shared)
 dav_fs_module (shared)
 dav_lock_module (shared)
 lua_module (shared)
 mpm_prefork_module (shared)
 proxy_module (shared)
 lbmethod_bybusyness_module (shared)
 lbmethod_byrequests_module (shared)
 lbmethod_bytraffic_module (shared)
 lbmethod_heartbeat_module (shared)
 proxy_ajp_module (shared)
 proxy_balancer_module (shared)
 proxy_connect_module (shared)
 proxy_express_module (shared)
 proxy_fcgi_module (shared)
 proxy_fdpass_module (shared)
 proxy_ftp_module (shared)
 proxy_http_module (shared)
 proxy_scgi_module (shared)
 proxy_wstunnel_module (shared)
 ssl_module (shared)
 systemd_module (shared)
 cgi_module (shared)
 php7_module (shared)

In CentOS 7, one can disable Apache modules by modifying configuration files located in /etc/httpd/conf.modules.d/, and commenting out lines including the LoadModule directive.

In short, I was able to determine which modules I didn’t need by guessing and checking. I disabled a module followed by running a syntax check for Apache configuration files:

[root@nowherelan]# httpd -t
Syntax OK

If you get a syntax error like
“Starting httpd: Syntax error on line 565 of /etc/httpd/conf/httpd.conf: Invalid command ‘IndexOptions’, perhaps misspelled or defined by a module not included in the server configuration”, you probably removed a module you needed.

Once done, restart Apache

[root@nowherelan]# systemctl restart httpd.service

Verify that your web application still functions properly after making these changes.

By the time I was done, I only had the following modules left:

[root@nowherelan]# httpd -M
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 access_compat_module (shared)
 alias_module (shared)
 authz_core_module (shared)
 autoindex_module (shared)
 dir_module (shared)
 headers_module (shared)
 log_config_module (shared)
 mime_module (shared)
 rewrite_module (shared)
 socache_shmcb_module (shared)
 unixd_module (shared)
 mpm_worker_module (shared)
 ssl_module (shared)
 systemd_module (shared)
 php7_module (shared)

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Restrict access to Directories in Apache

Objective

To harden an Apache web server.

Solution

Edit your Apache configuration file/etc/apache2/httpd.conf and add the following in the root level Directory directive:

<Directory />
    AllowOverride None
    AllowOverrideList None
    Options None
    Require all denied
</Directory>

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

When the AllowOverride directive is set to None and AllowOverrideList is set to None.htaccess files are completely ignored. In this case, the server will not even attempt to read .htaccess files in the filesystem.

The Options directive controls which server features are available in a particular directory. Options  can be set to None, in which case none of the extra features are enabled.

The Require directive tests whether an authenticated user is authorized according to a particular authorization provider and the specified restrictions. WithRequire all denied, access is denied unconditionally.

You will then want to enable certain abilities on a per-directory basis:

<Directory /var/www/html>
    Options +SymLinksIfOwnerMatch
    Require all granted
</Directory>

WithOptions +SymLinksIfOwnerMatch, the server will only follow symbolic links for which the target file or directory is owned by the same user id as the link.

WithRequire all granted, access is allowed unconditionally.

Verify that your web application still functions properly after making these changes.

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Secure cookies in Apache

Objective

Implement cookie HTTP header flag with HTTPOnly & Secure to protect website from XSS attacks

Solution

Without having HttpOnly and Secure flag in HTTP response header, it is possible to steal or manipulate web application session and cookies.

It’s better to manage this within the web application’s code. However, not all web applications have it implemented.

There are two optional settings each cookie can have set which largely address these issues: HttpOnly means that the cookies should not be accessible from client side scripts and Secure means that the cookie should only be sent across HTTPS requests.

Edit your Apache configuration file/etc/apache2/httpd.conf and add the following to your VirtualHost:

# Load the headers module
LoadModule headers_module modules/mod_headers.so

<VirtualHost *:443>
    # Secure Cookies
    Header always edit Set-Cookie ^(.*)$ "$1;HttpOnly;Secure"
</VirtualHost>

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Hide the PHP Version Number in HTTP Header in Apache

Objective

The default PHP configuration allows the server HTTP response header ‘X-Powered-By‘ to display the PHP version installed on a web server.

For server security reasons, it is recommended that you disable this information from attackers who might be targeting your server.

Solution

Edit your PHP configuration file/etc/php.ini and add the following:

; Decides whether PHP may expose the fact that it is installed on the server
; (e.g. by adding its signature to the Web server header). It is no security
; threat in any way, but it makes it possible to determine whether you use PHP
; on your server or not.
; http://php.net/expose-php
expose_php = Off

Restart Apache

[root@nowherelan]# systemctl restart httpd.service

Go to Geek Flare’s Test Site and check your website’s HTTP Response Header . It should no longer contain the HTTP response header ‘X-Powered-By‘ along with the version of PHP installed.

My System Configuration

  • CentOS 7
  • Apache 2.4
  • PHP 7.3

References

SSL/TLS Strong Encryption in Apache

Objective

Create an Apache web server which accepts strong encryption only.

The following will provide a strong SSL security compatible with all modern browsers. In short, they set a strong Forward Secrecy enabled ciphersuite, they disable SSLv2 and SSLv3, and enable OCSP Stapling.

Solution

Edit your Apache configuration file/etc/apache2/conf.d/ssl.conf and add the following:

SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off

# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

Use the following online tools to remotely check your site for which protocols and cipher suites it permits:

The following enables only the strongest ciphers:

SSLCipherSuite HIGH:!aNULL:!MD5

While with the following configuration you specify a preference for specific speed-optimized ciphers (which will be selected by mod_ssl, provided that they are supported by the client):

SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5
SSLHonorCipherOrder on

When choosing a cipher during an SSLv3 or TLSv1 handshake, normally the client’s preference is used. If the SSLHonorCipherOrder directive is enabled, the server’s preference will be used instead.

The CRIME attack uses SSL Compression in its exploit, so we can choose to disable that

SSLCompression off

The Online Certificate Status Protocol (OCSP) is a mechanism for determining whether or not a server certificate has been revoked, and OCSP Stapling is a special form of this in which the server, such as httpd and mod_ssl, maintains current OCSP responses for its certificates and sends them to clients which communicate with the server. Most certificates contain the address of an OCSP responder maintained by the issuing Certificate Authority, and mod_ssl can communicate with that responder to obtain a signed response that can be sent to clients communicating with the server.

Because the client can obtain the certificate revocation status from the server, without requiring an extra connection from the client to the Certificate Authority, OCSP Stapling is the preferred way for the revocation status to be obtained. Other benefits of eliminating the communication between clients and the Certificate Authority are that the client browsing history is not exposed to the Certificate Authority and obtaining status is more reliable by not depending on potentially heavily loaded Certificate Authority servers.

Because the response obtained by the server can be reused for all clients using the same certificate during the time that the response is valid, the overhead for the server is minimal.

Once general SSL support has been configured properly, enabling OCSP Stapling generally requires only very minor modifications to the httpd configuration — the addition of these two directives:

SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(128000)"

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Disable Trace HTTP Request in Apache

Objective

By default, the HTTP TRACE request method is enabled in Apache web server.

Having this enabled can allow Cross Site Tracing attack and potentially give an option to a hacker to steal cookie information.

Solution

Disable the HTTP TRACE request method.

Edit your Apache configuration file/etc/apache2/httpd.conf and add the following:

# Disable the HTTP TRACE request method
TraceEnable off

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

Use the online Request Method Security Scanner to remotely check your site for which HTTP request methods are allowed. It should list the TRACE method as “Method Not Allowed (405).”

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Limit HTTP Request Methods in Apache

Objective

The HTTP 1.1 protocol supports many request methods. Not all of these may be required for your site, and may in fact add a potential risk.

A default Apache configuration supports OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT method in HTTP 1.1 protocol.

However, typically most web applications only need GET, HEAD, POST request methods.

Solution

Disable all HTTP request methods except for GET, HEAD, POST.

Edit your Apache configuration file/etc/apache2/httpd.conf and add the following in the respective Directory directive

<Directory />
    <LimitExcept GET POST HEAD>
        deny from all
    </LimitExcept>
</Directory>

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

Verify that your web application still functions properly after disabling these request methods.

Use the online Request Method Security Scanner to remotely check your site for which HTTP request methods are allowed.

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Remove Server Version Banner in Apache

Objective

To not expose the version of Apache the web server is running, which can aide attackers.

Solution

Go to Geek Flare’s Test Site and check your website’s HTTP Response Header . With a default Apache configuration, the HTTP Response Header will expose Apache’s version and OS

Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips

Edit your Apache configuration file/etc/apache2/httpd.conf and add the following

ServerTokens Prod
ServerSignature Off

TheServerTokens will change Header to only display the web server type

The ServerSignature directive will remove the version information from the page generated by Apache.

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

Check your website’s HTTP Response Header again. Now it should only show

Server: Apache

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Secure Your Site with the X-XSS-Protection HTTP Header in Apache

Objective

X-XSS-Protection is a security header to prevent some level of cross-site scripting (XSS) vulnerabilities.

Solution

Edit your Apache configuration file/etc/apache2/httpd.conf and add the following to your VirtualHost.

# Load the headers module
LoadModule headers_module modules/mod_headers.so

<VirtualHost *:443>
    # X-XSS-Protection
    Header set X-XSS-Protection "1; mode=block"
</VirtualHost>

With a value of “1; mode=block” XSS filter will be enabled will prevent rendering the page if an attack is detected.

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

Go to Geek Flare’s Test Site and test your site . The output will tell you if you have everything correct.

My System Configuration

  • CentOS 7
  • Apache 2.4

References

Secure your WordPress site with the Content Security Policy (CSP) HTTP Header in Apache

Objective

Content Security Policy (CSP) is a HTTP security header to prevent cross-site scripting, clickjacking, and code injection attack.

CSP instruct browsers to load content only from allowed sources. It helps you to restrict the sources and types of content that may be loaded and processed by visitor browsers.

Solution

Edit your Apache configuration file/etc/apache2/httpd.conf and add the following to your VirtualHost.

Below is a good starter policy for a site. It allows images, scripts, AJAX, and CSS from the same origin, and does not allow any other resources to load (i.e., object, frame, media, etc).

# Load the headers module
LoadModule headers_module modules/mod_headers.so

<VirtualHost *:443>
    # Content-Security-Policy Header
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';"

</VirtualHost>

However, you will need to customize this to meet your specific needs. Use the Chrome browser developer tools console to display blocks encountered by your browser. You may also want to disable browser extensions during your testing to avoid issues.

Below is a good starter policy for a WordPress site. It allows images, scripts, AJAX, and CSS from the same origin, and other resources to load only from specifically named sites.

# Load the headers module
LoadModule headers_module modules/mod_headers.so

<VirtualHost *:443>
    # Content-Security-Policy Header
    Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: http: https: *.gravatar.com *.wp.com *.wordpress.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' http: https: *.wp.com *.wordpress.com; style-src 'self' 'unsafe-inline' http: https: fonts.googleapis.com *.wp.com *.wordpress.com; font-src 'self' data: http: https: fonts.googleapis.com themes.googleusercontent.com *.wp.com *.wordpress.com; frame-src 'self' 'unsafe-inline' 'unsafe-eval' http: https: *.wp.com *.wordpress.com"
</VirtualHost>

Reload Apache

[root@nowherelan]# systemctl reload httpd.service

Go to Geek Flare’s Test Site and test your site . The output will tell you if you have everything correct.

My System Configuration

  • CentOS 7
  • Apache 2.4
  • WordPress version 5.0

References