Securing WordPress using a combination of configuration changes and plugins.
Sources
1. Install iThemes Security
- limit login attempts
- bruteforce
- hide /wp-admin.
- Many other features
1. Add keys to wp-config.php
/* Disable File Editing */
define('DISALLOW_FILE_EDIT', true);
-
just move the wp-config.php one level above the wordpress installation and wp will detect it automatically. If you get some error reloading the site maybe is for wrong wp-config.php file permissions
-
For a custom create the new custom-file with the settings and import it in the wp-config.php
<?php
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . '../path/to/wp-config.php');
- if your site is broken after moving the wp-config check if the file that you are trying to import have the correct permissions. try running
sudo chown www-data:www-data /path/to/my/moved/config/wp-substitute-config.php
From this point the edits have to be added at the end of the .htacces file
# Restrinct wp-config.php
<Files wp-config.php>
order allow,deny
deny from all
</Files>
# Restrinct .htaccess
<Files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
</Files>
# Block wp-includes folder and files
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
# prevent username enumaration
RewriteCond %{QUERY_STRING} author=d
RewriteRule ^ /? [L,R=301]
# prevent script injection
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
# disable xml-rpc.php
<files xmlrpc.php>
order allow,deny
deny from all
</files>
# limit login acces to specific ip
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin(\/)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin/$
RewriteCond %{REMOTE_ADDR} !^63\.224\.182\.124$
RewriteCond %{REMOTE_ADDR} !^96\.81\.205\.229$
RewriteRule ^(.*)$ - [R=403,L]
</IfModule>
# prevent directory listing
Options All -Indexes
-
From this point the edits have to be added in the theme functions.php file
- Directly disable it
add_filter ('json_enabled', '__return_false');
add_filter ('json_jsonp_enabled', '__return_false');
- Or require the authentication for use it wp sudjestion
add_filter( 'rest_authentication_errors', function( $result ) {
// If a previous authentication check was applied,
// pass that result along without modification.
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
// No authentication has been performed yet.
// Return an error if user is not logged in.
if ( ! is_user_logged_in() ) {
return new WP_Error(
'rest_not_logged_in',
__( 'You are not currently logged in.' ),
array( 'status' => 401 )
);
}
// Our custom authentication check should have no effect
// on logged-in requests
return $result;
});
// Insert into your functions.php and have fun by creating login error msgs
function guwp_error_msgs() {
// insert how many msgs you want as array items. it will be shown randomly (html is allowed)
$custom_error_msgs = [
'<strong>WRONG</strong>: please controll the password or the username'
];
// get and returns a random array item to show as the error msg
return $custom_error_msgs[array_rand($custom_error_msgs)];
}
add_filter( 'login_errors', 'guwp_error_msgs' );
function wpbeginner_remove_version() {
return '';
}
add_filter('the_generator', 'wpbeginner_remove_version');
-
From this point the edits have to be added in a newly created .htacces file inside wp-content/uploads/
# Kill PHP Execution
<Files *.php>
deny from all
</Files>