Tutorial Website securities
Webserver Apache security
Server configuration
# [ Server Signature ] (only if like me you don't care about defiance) ServerSignature Off # [ Server tokens info ] # Set to one of: Full | OS | Minimal | Minor | Major | Prod ServerTokens Prod # [ Trace Mode ] TraceEnable Off # [ Prevent DDOS ] # Limit timeout to 45 Timeout 45 # Limit request to 2Mb LimitRequestBody 2096576 # Limit xml size to 1Mb LimitXMLRequestBody 10485760
HTTPS
Check your level of security on web sites like www.ssllabs.com, then set your configuration to prevent exploit.This is the configuration i use for an A ranking :
# [ HTTPS Site ]SSLEngine on SSLOptions +StrictRequire SSLProxyEngine off SSLHonorCipherOrder on #SSL Compression (CRIME attack) SSLCompression off #HSTS Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" SSLProtocol -all +TLSv1 +TLSv1.1 +TLSv1.2 SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 SSLCertificateFile /opt/web/ssl/home.frogg.fr.crt SSLCertificateKeyFile /opt/web/ssl/home.frogg.fr.key SSLCertificateChainFile /opt/web/ssl/sub.class1.server.ca.pem SSLRequireSSL
Blocking bad bots & bad requests
- Limit request method to GET, HEAD & POST
- Block empty user agent & suspicous user agent
- Bloc request trageting localhost (if you are not configured to receive request on it)
- Bloc request not strating with / (if you don't use proxy)
- Bloc suspicious referer, a normal referer should start with http or being empty
This is the configuration i use to redirect bad traffic to 406 page :
RewriteCond %{HTTP_USER_AGENT} ^-?$|curl|perl|python|\\x.*?\\x [NC,OR] RewriteCond %{HTTP_HOST} localhost [OR] RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST)$ [OR] RewriteCond %{REQUEST_URI} !^/ [OR] RewriteCond %{HTTP_REFERER} "!^$|^http" RewriteRule .* - [END,R=406]
File upload security
Upload system
- Check File extensions and Mime Types
- Make sure that the file name not bigger than 250 characters.
- Save file with a new filename
- Use move_uploaded_file function (for php)
Upload folder
prevent file execution in upload folderRemoveHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi .exe Options -Indexes Options -ExecCGI php_flag engine off
Send mail security
$to = "bob@domain_example.co.za"; $subject = $_REQUEST["subject"]; $body = $_REQUEST["body"]; $email = $_REQUEST["email"]; function is_valid_email($email) { return preg_match('#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([^\s]+\.+[a-z]{2,6}))$#si', $email); } function contains_bad_str($str_to_test) { $bad_strings = array( "content-type:" ,"mime-version:" ,"multipart/mixed" ,"Content-Transfer-Encoding:" ,"bcc:" ,"cc:" ,"to:" ); foreach($bad_strings as $bad_string) { if(eregi($bad_string, strtolower($str_to_test))) { echo "$bad_string found. Suspected injection attempt - mail not being sent."; exit; } } } function contains_newlines($str_to_test) { if(preg_match("/(%0A|%0D|\\n+|\\r+)/i", $str_to_test) != 0) { echo "newline found in $str_to_test. Suspected injection attempt - mail not being sent."; exit; } } if($_SERVER['REQUEST_METHOD'] != "POST"){ echo("Unauthorized attempt to access page."); exit; } if (!is_valid_email($email)) { echo 'Invalid email submitted - mail not being sent.'; exit; } contains_bad_str($email); contains_bad_str($subject); contains_bad_str($body); contains_newlines($email); contains_newlines($subject); $headers = "From: $email"; mail($to, $subject, $body, $headers);from http://www.phpbuilder.com/columns/ian_gilfillan20060412.php3?page=2
A php function exist to test email validity :
filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))