Archive for the ‘security’ Category
Some bot blocking htaccess hacks for WordPress
There are some great security plugins out there. But all WordPress security plugins require that the bot use the front door to the website. Otherwise the security plugin isn’t turned on.
Your .htaccess file provides better coverage and is more efficient. I realize not everyone has access to .htaccess and that is why bot blocker, security plugin and other security plugins exist. But if you have access to .htaccess that is where you should be doing your security.
This will not stop all bots but should slow them down quite a bit.
Improved .htaccess file
^ – starts with
$ – ends with
———————————————————————————
# block known trouble makers dumb enough to
# announce who they are
SetEnvIfNoCase User-Agent “^EmailSiphon” bad_bot
SetEnvIfNoCase User-Agent “^EmailWolf” bad_bot
SetEnvIfNoCase User-Agent “^ExtractorPro” bad_bot
SetEnvIfNoCase User-Agent “^CherryPicker” bad_bot
SetEnvIfNoCase User-Agent “^NICErsPRO” bad_bot
SetEnvIfNoCase User-Agent “^Teleport” bad_bot
SetEnvIfNoCase User-Agent “^EmailCollector” bad_bot
SetEnvIfNoCase User-Agent “^LinkWalker” bad_bot
SetEnvIfNoCase User-Agent “^Zeus” bad_bot
SetEnvIfNoCase User-Agent “^botpaidtoclick” bad_bot
SetEnvIfNoCase User-Agent “^Click Bot” bad_bot
SetEnvIfNoCase User-Agent “^WebRipper” bad_bot
SetEnvIfNoCase User-Agent “^Wget” bad_bot
SetEnvIfNoCase User-Agent “^Snoopy” bad_bot
SetEnvIfNoCase User-Agent “^Security Kol” bad_bot
SetEnvIfNoCase User-Agent “^libwww-perl” bad_bot
SetEnvIfNoCase User-Agent “^Java” bad_bot
SetEnvIfNoCase User-Agent “^DataCha0s” bad_bot
SetEnvIfNoCase User-Agent “^Grazer” bad_bot
SetEnvIfNoCase User-Agent “^lwp-request” bad_bot
SetEnvIfNoCase User-Agent “^lwp-trivial” bad_bot
SetEnvIfNoCase User-Agent “^Morpheus” bad_bot
SetEnvIfNoCase User-Agent “^Site Sniper” bad_bot
SetEnvIfNoCase User-Agent “^Winnie Poh” bad_bot
SetEnvIfNoCase User-Agent “^curl” bad_bot
SetEnvIfNoCase User-Agent “^Akregator” bad_bot
SetEnvIfNoCase User-Agent “^ac-baidu” bad_bot
SetEnvIfNoCase User-Agent “(Ubuntu-feisty)$” bad_bot
<Limit GET POST>
Order Allow,Deny
Allow from all
Deny from env=bad_bot
</Limit>
# block directory browsing
Options All -Indexes
# protect some files
<files wp-config.php>
order allow,deny
deny from all
</files>
<files .htaccess>
order allow,deny
deny from all
</files>
# block bot registrations and send them to the front door
# if you try to register and your accept statement only has */*
# I’ll think you’re a bot
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-login\.php*
RewriteCond %{HTTP_ACCEPT} ^\*\/\*$
RewriteRule (.*) http://yourdomain.com/ [R=301,L]
</IfModule>
———————————————————————————
Additional resources:
Perishable Press Stupid htaccess tricks
Almost Perfect htaccess File for WordPress
Good WP database checks to run
Every so often it’s good to just run a quick pass on your WordPress database and look for troubles.
There are two things I check for: users who don’t comment, and iframes and scripts inside of posts.
You can easily bookmark SQL queries in phpMyAdmin, I do this and try to run the scripts every week or so.
To check for iframes and scripts added to your posts log on to phpMyAdmin and then click the SQL tab and run the following command:
SELECT *
FROM wp_posts
WHERE post_content LIKE '%iframe%'
UNION
SELECT *
FROM wp_posts
WHERE post_content LIKE '%noscript%'
UNION
SELECT *
FROM wp_posts
WHERE post_content LIKE '%display:none%'
UNION
SELECT *
FROM wp_posts
WHERE post_content LIKE '%ekibastos%'
UNION
SELECT *
FROM wp_posts
WHERE post_content LIKE '%visibility:hidden%';
This looks for hidden things in your posts. If you get any results back you should check that post very carefully for things you did not put in it.
Users who register and don’t comment are likely bots who got through the bot net, or spammers planning to come back later. I delete all users who register but don’t comment soon thereafter.
To check for users who haven’t commented run the following SQL query
SELECT user_login, user_email, date_format( user_registered, '%M %d %Y' ) AS user_registration_date
FROM wp_users
WHERE wp_users.user_login NOT
IN (
SELECT comment_author
FROM wp_comments
)
LIMIT 0 , 30
Another optimization you’ll want to make is to delete all those post revisions, they multiply quickly.
DELETE FROM wp_posts WHERE post_type = "revision";
And finally optimize your tables
OPTIMIZE TABLE `wp_comments` , `wp_links` , `wp_options` , `wp_postmeta` , `wp_posts` , `wp_terms` , `wp_term_relationships` , `wp_term_taxonomy` , `wp_usermeta` , `wp_users`;
Check for altered files on webhost
Every time I change webhosts I have to dust off files and slightly re-arrange the way I do security.
Instead of running the file check through a WP plugin I decided to run it from a command line and email myself the results.
The following PHP code will check for altered files in the previous 7 days ( $days = 7 ) and email you the files altered.
You should give this code a random file name and place it somewhere off the beaten path on your server. I set permissions to r–r–r–.
<?php
/*
Tripwire for webserver to tell when files altered or have 777 permissions
Author: Linda MacPhee-Cobb
Author URI: http://timestocome.com
Support URI: http://herselfswebtools.com
*/
// date
date_default_timezone_set('UTC');
// info we need
$date = time(); // current date+time
$one_day = 86400; // number of seconds in one day
$days = 7; // user selected number of days back to check files
$dir_count = 0; // init loop
$directories_to_read[0] = getcwd() . "/"; // start at the beginning
$i = 0; // loop counter
// time diff
$go_back = $one_day * $days;
$diff = $date - $go_back;
//email
$to = 'you@gmail.com';
$subject = 'file check';
$headers = "From: webmaster@your_domain.com";
$message = "";
while ( $i <= $dir_count ){
// get file info
$current_directory = $directories_to_read[$i];
$read_path = opendir( $directories_to_read[$i] );
while ( $file_name = readdir( $read_path)){
if (( $file_name != '.' )&&( $file_name != '..' )){
if ( is_dir( $current_directory . "/" . $file_name ) == "dir" ){
// need to grab files from each directory all the way down to leaves
$d_file_name = "$current_directory" . "$file_name";
$dir_count++;
$directories_to_read[$dir_count] = $d_file_name . "/";
}else{
$file_name = "$current_directory" . "$file_name";
// if time modified newer than x days print - else skip
if ( (filemtime( $file_name)) > $diff ){
$message .= "\nFILE ALTERED $file_name";
$date_changed = filectime( $file_name );
$pretty_date = date( "F j, Y g:i a", $date_changed);
$message .= " ::: $pretty_date " ;
}
}
}
}
closedir ( $read_path );
$i++;
}
$mail_sent = @mail( $to, $subject, $message, $headers );
?>
