Leaving your wp-login.php script or wp-admin folder accessible from the internet allows for bruteforcing of your passwords
My way of solving this is by creating a randomly named folder e.g. “asbra” with som php code that sets a cookie which is required by the .htaccess file.
<?php $admin_cookie_code="329847348597"; setcookie("AsbraSession",$admin_cookie_code,0,"/"); header("Location: ../wp-admin/index.php"); ?>
Then paste the following at the bottom of your .htaccess file
############################### # BEGIN Asbra AB <j@asbra.nu> # ############################### # # Cookie based access to administration # <IfModule mod_rewrite.c> RewriteEngine On # Only allow admin if ASBRA Cookie has been set correctly RewriteCond %{REQUEST_URI} /wp-login.php RewriteCond %{HTTP_COOKIE} !AsbraSession=329847348597 RewriteRule .* - [L,F] RewriteCond %{REQUEST_URI} /wp-admin RewriteCond %{HTTP_COOKIE} !AsbraSession=329847348597 RewriteRule .* - [L,F] # Disable WordPress include-only files 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] # Do we really need the Trace, Delete and Track Request Methods ? RewriteCond %{REQUEST_METHOD} ^(TRACE|DELETE|TRACK) [NC] RewriteRule ^(.*)$ - [F,L] # Block User ID Phishing Requests RewriteCond %{QUERY_STRING} ^author=([0-9]*) RewriteRule .* - [L,F] #RewriteRule .* http://example.com/? [L,R=302] </IfModule> # # And then some extra file/uri security # # This stops hackers from trying thousands of passwords in only a few requests <Files xmlrpc.php> order allow,deny deny from all </Files> <Files wp-cron.php> order allow,deny deny from all </Files> <Files wp-links-opml.php> order allow,deny deny from all </Files> <files ~ "^.*\.([Hh][Tt][Aa])"> order allow,deny deny from all </files> <files wp-config.php> order allow,deny deny from all </files> # Are you using the REST API? <files wp-json> order allow,deny deny from all </files> # # Set extra headers for clients # <IfModule mod_headers.c> # nosniff - Blocks a request if the requested type is "style" and the MIME type is not "text/css", or "script" and the MIME type is not a JavaScript MIME type. Header set X-Content-Type-Options nosniff # Enable the cross-site scripting (XSS) filter in users browser Header set X-XSS-Protection "1; mode=block" # Require HTTPS (Be very careful! this is saved in the clients browser for 2 years!) # Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;" # Prevent Fraudulent Iframing Header set X-Frame-Options "SAMEORIGIN" # Add your own! Only allow includes from SELF and from CDN (Unsafe inline is needed if wee want inline javascript and CSS) Header add Content-Security-Policy "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: http://cdn.asbra.nu;" # Dont give away referer on outgoing links Header always set Referrer-Policy "same-origin" # Block client from certain features Header set Feature-Policy "microphone 'none';camera 'none';geolocation 'self';payment 'none';sync-xhr 'self'" # Unset headers revealing versions strings Header unset X-Powered-By Header unset X-Pingback Header unset SERVER </IfModule> ################ # END Asbra AB # ################
We also want to limit the upload folder. Place this .htaccess in your wp-contents/ folder
Order deny,allow Deny from all <Files ~ ".(xml|css|jpe?g|png|gif|js)$"> Allow from all </Files>
And just in case someone gets a hold och your backend, limit their possibility to edit your files by placing the following at the end of wp-config.php
define('DISALLOW_FILE_EDIT', true);
WordPress will install minor updates automatically, to enable all core updates, including minor and major:
define( 'WP_AUTO_UPDATE_CORE', true );