Manage cookies that are used for advertising, such as ad personalization, remarketing, and ad effectiveness analysis.
2.14.1.17. Hacking protection for WordPress sites
Attention!
Before performing any actions, create backups of your site and database.- Regularly update WordPress, themes, and plugins. Currently, WordPress CMS accounts for over 30% of all sites worldwide. Due to its widespread use, WordPress is a popular target for hackers. Since WordPress is an open-source CMS, anyone can access the code to learn and improve it. However, this also means that hackers can study it and find ways to infiltrate sites.
Whenever a vulnerability is discovered, WordPress developers make every effort to release an update that fixes the problem. If you are not using the latest version of WordPress, you are using software with known security vulnerabilities. - Delete all unused themes from the
wp-content/themesdirectory and unused plugins from thewp-content/pluginsdirectory. Storing free themes and plugins significantly increases the likelihood of your site being hacked. Even if a theme or plugin is inactive, it still allows malicious scripts to be opened from thewp-content/themes/theme_nameorwp-content/plugins/plugin_namedirectory. - More than half of free WordPress themes are infected or vulnerable. If you download premium themes from a resource where they are available for free, there is a high probability that they contain malicious code or spam links.
- Disable the display of the WordPress version. Malicious users will not be able to identify the version, and therefore will not be aware of any vulnerabilities. To do this, open the file
wp-content/themes/theme_name/functions.phpand add the following code after the first line:function remove_wordpress_version_number() { return ''; } add_filter('the_generator', 'remove_wordpress_version_number'); function remove_version_from_scripts( $src ) { if ( strpos( $src, '?ver=' ) ) $src = remove_query_arg( 'ver', $src ); return $src; } add_filter( 'style_loader_src', 'remove_version_from_scripts'); add_filter( 'script_loader_src', 'remove_version_from_scripts'); - Move the configuration file
wp-config.phpto the directory above the current one. Thewp-config.phpfile contains the basic settings for your site and is the most important file in the root directory of the site. In the current WordPress architecture, the configuration file is checked with the highest priority. Thus, even if it is stored in a folder above the root directory, WordPress will still be able to see it. You need to move this file from the/home/hosting_account_name/site_name/www/directory to the/home/hosting_account_name/site_name/directory. Warning! This recommendation only applies if you are using a single subdomain. - Change the database prefix. You can do this using phpMyAdmin:
- Copy the resulting list of all tables in the database and create a similar query for each table:
RENAME TABLE `wp_comments` TO `wpnew1_comments`; - Execute the created queries:

- To ensure that the prefix
wp_is no longer in use, execute the following query:SELECT * FROM `wpnew1_options` WHERE `option_name` LIKE '%wp_%' - Manually change the prefix to a new one using the "Change" button:

- Perform the same actions after executing the following query:
SELECT * FROM `wpnew1_usermeta` WHERE `meta_key` LIKE '%wp_%' - As a final step, open the configuration file
wp-config.phpand change the prefix to the new one:
- Change the default administrator login
admin:- Open it and find the login
adminin theuser_logincolumn. Click "Change", enter the new administrator login, and save the changes:
- Change the URL of the admin panel. To do this, use the Protect Your Admin plugin:
- Install the plugin, open the plugin menu, replace the URL, and click "Save":

- In the "Settings → Permalinks" section, set the "Post name" option:
The admin panel will now be accessible at example.com/wpmyadmin.
- Deny access to the
xmlrpc.phpfile. To do this, add one of the following restrictions to the.htaccessfile in the root directory of the site:# Redirect to local address. The log will contain response code 301.. RewriteRule ^xmlrpc\.php$ "http\:\/\/127\.0\.0\.1\/" [R=301,L] # We deny access to the file. The log will contain response code 403. RewriteRule ^xmlrpc.php$ - [F,L] - Disable the execution of PHP files in the uploads directory. This is a common place for viruses to be uploaded. To prevent malicious code from being executed in the event of a hack, add the following code to the
wp-content/uploads/.htaccessfile:<Files ~ "\.(php)$"> Order allow,deny Deny from all </Files> - Restrict access to the admin panel by IP. This recommendation is suitable for those who have a static IP address. Add the following code to the
.htaccessfile in the root directory of the site:RewriteEngine on RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$ [OR] RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ RewriteCond %{REMOTE_ADDR} !^127.0.0.1$ RewriteRule ^(.*)$ - [R=403,L]Replace
127.0.0.1with your IP address. - A small firewall for the site. These rules may slow down the site, as each request to the site will be analyzed using them. If you notice a significant decrease in the speed of the site, you should not use these rules. Instead, try using the Wordfence Security — Firewall & Malware Scan plugin.
Add the firewall code to the.htaccessfile in the root directory of the site:<IfModule mod_rewrite.c> RewriteEngine On # XSS blocking RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR] # Blocking the setting of PHP GLOBALS variables via URL RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR] # Block the ability to change the _REQUEST variable via URL RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) # Blocking MySQL injections, RFI, base64, etc. RewriteCond %{QUERY_STRING} (javascript:)(.*)(;) [NC,OR] RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR] RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR] RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC,OR] RewriteCond %{QUERY_STRING} \=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} [NC,OR] RewriteCond %{QUERY_STRING} (\.\./|\.\.) [OR] RewriteCond %{QUERY_STRING} ftp\: [NC,OR] RewriteCond %{QUERY_STRING} http\: [NC,OR] RewriteCond %{QUERY_STRING} https\: [NC,OR] RewriteCond %{QUERY_STRING} \=\|w\| [NC,OR] RewriteCond %{QUERY_STRING} ^(.*)/self/(.*)$ [NC,OR] RewriteCond %{QUERY_STRING} ^(.*)cPath=http://(.*)$ [NC,OR] RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} (\<|%3C).*iframe.*(\>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} (<|%3C)([^i]*i)+frame.*(>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|%3D) [OR] RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR] RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [NC,OR] RewriteCond %{QUERY_STRING} ^.*(\[|\]|\(|\)|<|>).* [NC,OR] RewriteCond %{QUERY_STRING} (NULL|OUTFILE|LOAD_FILE) [OR] RewriteCond %{QUERY_STRING} (\./|\../|\.../)+(motd|etc|bin) [NC,OR] RewriteCond %{QUERY_STRING} (localhost|loopback|127\.0\.0\.1) [NC,OR] RewriteCond %{QUERY_STRING} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR] RewriteCond %{QUERY_STRING} concat[^\(]*\( [NC,OR] RewriteCond %{QUERY_STRING} union([^s]*s)+elect [NC,OR] RewriteCond %{QUERY_STRING} union([^a]*a)+ll([^s]*s)+elect [NC,OR] RewriteCond %{QUERY_STRING} (;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|order|script|set|md5|benchmark|encode) [NC,OR] RewriteCond %{QUERY_STRING} (\\|\.\.\.|\.\./|~|`|<|>|\|) [NC,OR] RewriteCond %{QUERY_STRING} (boot\.ini|etc/passwd|self/environ) [NC,OR] RewriteCond %{QUERY_STRING} (thumbs?(_editor|open)?|tim(thumb)?)\.php [NC,OR] RewriteCond %{QUERY_STRING} (sp_executesql) [NC] RewriteCond %{QUERY_STRING} (eval\() [NC,OR] RewriteCond %{QUERY_STRING} ([a-z0-9]{2000,}) [NC,OR] RewriteRule ^(.*)$ - [F,L] # Blocking known Shells RewriteEngine on RewriteCond %{REQUEST_URI} .*((php|my)?shell|remview.*|phpremoteview.*|sshphp.*|pcom|nstview.*|c99|r57|webadmin.*|phpget.*|phpwriter.*|fileditor.*|locus7.*|storm7.*).(p?s?x?htm?l?|txt|aspx?|cfml?|cgi|pl|php[3-9]{0,1}|jsp?|sql|xml) [NC,OR] RewriteCond %{REQUEST_METHOD} (GET|POST) [NC] RewriteCond %{QUERY_STRING} ^(.*)=(/|%2F)(h|%68|%48)(o|%6F|%4F)(m|%6D|%4D)(e|%65|%45)(.+)?(/|%2F)(.*)(/|%2F)(.*)$ [OR] RewriteCond %{QUERY_STRING} ^work_dir=.*$ [OR] RewriteCond %{QUERY_STRING} ^command=.*&output.*$ [OR] RewriteCond %{QUERY_STRING} ^nts_[a-z0-9_]{0,10}=.*$ [OR] RewriteCond %{QUERY_STRING} ^c=(t|setup|codes)$ [OR] RewriteCond %{QUERY_STRING} ^act=((about|cmd|selfremove|chbd|trojan|backc|massbrowsersploit|exploits|grablogins|upload.*)|((chmod|f)&f=.*))$ [OR] RewriteCond %{QUERY_STRING} ^act=(ls|search|fsbuff|encoder|tools|processes|ftpquickbrute|security|sql|eval|update|feedback|cmd|gofile|mkfile)&d=.*$ [OR] RewriteCond %{QUERY_STRING} ^&?c=(l?v?i?&d=|v&fnot=|setup&ref=|l&r=|d&d=|tree&d|t&d=|e&d=|i&d=|codes|md5crack).*$ [OR] RewriteCond %{QUERY_STRING} ^(.*)([-_a-z]{1,15})=(chmod|chdir|mkdir|rmdir|clear|whoami|uname|unzip|gzip|gunzip|grep|more|umask|telnet|ssh|ftp|head|tail|which|mkmode|touch|logname|edit_file|search_text|find_text|php_eval|download_file|ftp_file_down|ftp_file_up|ftp_brute|mail_file|mysql|mysql_dump|db_query)([^a-zA-Z0-9].+)*$ [OR] RewriteCond %{QUERY_STRING} ^(.*)(wget|shell_exec|passthru|system|exec|popen|proc_open)(.*)$ RewriteRule .* - [F] </IfModule>
(6)

