Apache Security tips and tricks for securing Apache Web Servers using htaccess, httpd.conf, and other built-in techniques to thwart attackers. This really should be required reading for any Apache admin or user because these little tricks are so easy to do.


| .htaccess Tutorial Index |

Security with Apache htaccess


CHMOD your files

Chmod your .htpasswd files 640, .htaccess files 644. Chmod php files 600, chmod files that you really dont want people to see as 400 (wp-config.php, config.php) and NEVER chmod 777, if something requires write access use 766 first then 775

Prevent access to .htaccess and .htpasswd files

You will almost never have to do this unless you are working with your config file for the whole server. Anyway its easy to test if you need this.

<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>

Show Source Code instead of executing

If you’d rather have .pl, .py, or .cgi files displayed in the browser as source rather than be executed as scripts

RemoveHandler cgi-script .pl .py .cgi

Securing directories: Remove the ability to execute scripts

This is cool, you are basically categorizing all files that end in certain extensions so that they fall under the jurisdiction of the -ExecCGI command, which also means -FollowSymLinks. And the opposite is also true, +ExecCGI also turns on +FollowSymLinks

AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi 
Options -ExecCGI

ErrorDocuments in htaccess

Note: 401 Errors only redirect to a local file, not an external file. Also, When you use an external link, don’t do an external link to your site or you will cause a loop that will hurt your SEO.

Article: ErrorDocument Info and Examples, HTTP Status Codes

Common STATUS Codes and ErrorDocument Implementations

NOTE:
You will most definately want to check out and use the Google 404 Error Page.

#BAD_REQUEST
ErrorDocument 400 /cgi-bin/e400.php
 
#UNAUTHORIZED
ErrorDocument 401 /cgi-bin/e401.php
 
#FORBIDDEN
ErrorDocument 403 /cgi-bin/e403.php
 
#NOT_FOUND
ErrorDocument 404 /cgi-bin/e404.php
 
#METHOD_NOT_ALLOWED
ErrorDocument 405 /cgi-bin/e405.php
 
#REQUEST_TIME_OUT
ErrorDocument 408 /cgi-bin/e408.php
 
#GONE
ErrorDocument 410 /cgi-bin/e410.php
 
#LENGTH_REQUIRED
ErrorDocument 411 /cgi-bin/e411.php
 
#PRECONDITION_FAILED
ErrorDocument 412 /cgi-bin/e412.php
 
#REQUEST_ENTITY_TOO_LARGE
ErrorDocument 413 /cgi-bin/e413.php
 
#REQUEST_URI_TOO_LARGE
ErrorDocument 414 /cgi-bin/e414.php
 
#UNSUPPORTED_MEDIA_TYPE
ErrorDocument 415 /cgi-bin/e415.php
 
#INTERNAL_SERVER_ERROR
ErrorDocument 500 /cgi-bin/e500.php
 
#NOT_IMPLEMENTED
ErrorDocument 501 /cgi-bin/e501.php
 
#BAD_GATEWAY
ErrorDocument 502 /cgi-bin/e502.php
 
#SERVICE_UNAVAILABLE
ErrorDocument 503 /cgi-bin/e503.php
 
#VARIANT_ALSO_VARIES
ErrorDocument 506 /cgi-bin/e506.php

When using CGI PHP, php 404 Error example

You may also have to send a “Status” header in addition to the HTTP 1/1 header.

<?php
ob_start();
header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found');
?>
<html>
<body>
Error message
</body>
</html>

An example 404 Error page in perl cgi

#!/usr/local/bin/perl
 
print "Status: 503 Service Temporarily Unavailable\n";
print "Content-Type: text/html; charset=UTF-8;\n";
print "Retry-After: 3600\r\n\r\n";
print "
<!DOCTYPE HTML PUBLIC \\"-//IETF//DTD HTML 2.0//EN\\">
\n
<html>
<head>\n
<title>503 Service Temporarily Unavailable</title>
\n
print "
</head>
<body>
\n
<h1>Service Temporarily Unavailable</h1>
\n
<p>The server is temporarily unable to service your\n";
print "request due to maintenance downtime or capacity\nproblems. Please try again later.</p>
\n
</body>
</html>
";

ErrorDocuments generated by Apache

Have a top.html

<!--#if expr="! $CONTENT_LANGUAGE"
-->
<!--#set var="CONTENT_LANGUAGE" value="en"
-->
<!--#endif
-->
<!--#if expr="! $CHARACTER_ENCODING"
-->
<!--#set var="CHARACTER_ENCODING" value="ISO-8859-1"
-->
<!--#endif
-->
<?xml version="1.0" encoding="<!--#echo var="CHARACTER_ENCODING" -->"?>
<!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" lang="<!--#echo var="CONTENT_LANGUAGE" -->
" xml:lang="
<!--#echo var="CONTENT_LANGUAGE" -->
">
<head>
    <title>
    <!--#echo encoding="none" var="TITLE" -->
    </title>
    <link rev="made" href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->
" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
    body { color: #000000; background-color: #FFFFFF; }
    a:link { color: #0000CC; }
    p, address {margin-left: 3em;}
    span {font-size: smaller;}
/*]]>*/-->
</style>
</head><body>
<h1>
    <!--#echo encoding="none" var="TITLE" -->
</h1>
<p>

bottom.html

</p>
<p>
<!--#include virtual="../contact.html.var" -->
</p>
 
<h2>Error
    <!--#echo encoding="none" var="REDIRECT_STATUS" -->
</h2>
<address>
<a href="/">
<!--#echo var="SERVER_NAME" -->
</a><br />
<!--#config timefmt="%c" -->
<span>
<!--#echo var="DATE_LOCAL" -->
<br />
<!--#echo var="SERVER_SOFTWARE" -->
</span>
</address>
</body>
</html>

New

errordocument 401 /error/401.html
AuthType Basic
AuthName "site"
AuthUserFile <path to .htpasswd>
AuthGroupFile /dev/null
Require valid-user
SetEnvIf Request_URI "^/(error/401\.html¦robots\.txt)$" allow_all
Order allow,deny
Allow from env=allow_all
Satisfy any

External Apache htaccess security Articles


htaccess Guide Sections

| .htaccess Tutorial Index |

Security equipment Security systems and equipment, security cameras and personal protection products! If you need security, check here!


Related Articles