optymalizacja-cms-wordpress

Optimization and security / CMS WordPress

Tags: Audit WordPress, optimization, security, seo, websites, WordPress

iREBU Agencja Interaktywa / Studio graficzne

Specjalista Wordpress / Programowanie / Projekty graficzne / Wydruk


I. Data backup

Before I start working, first I make a copy of the website.

  • BackUpWordPress.

II. Updating CMS WordPress and add-ons

The first step of optimization is to update the system and add-ons to the latest version. It’s crucial, because from time to time authors fix bugs, solve security issues, increase speed or add new interesting functions.

III. Optimizing load speed

Websites installed on WordPress often load slowly, especially in the evenings, when hosts are the most loaded. First, I change PHP version on server to 7 and disable unnecessary plugins. Then, I install a plugin that buffers PHP code, which makes dynamic pages load in a static form, and reduces the weight of website code and images. It’s also useful to configure the website for global CDN cloudflare.com, so that the website will be downloaded from a localization closest to the user.

  • P3 Plugin Performance Profiler, analysis and deactivating redundant add-ons,
  • W3 Total Cache, WP Super Cache, LiteSpeed Cache, PHP code buffering,
  • Autoptimize, website code reduction,
  • Jetpack z WordPress.com / Photon, pictures optimization, compression and integration with CDN WordPress,
  • .htaccess optimization, modifying buffering time of the code by the browser, code compression for the browser:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.(php|html|htm|css|js|ico|jpg|jpeg|png|gif|swf|json|txt|eot|woff|woff2|ttf|svg)$ empty [R=404,L]

<FilesMatch "\.(css|js|ico|jpg|jpeg|png|gif|swf|xml|json|txt|eot|woff|woff2|ttf|svg|pdf|doc|xls)$">
 RequestHeader unset Cookie
 Header unset Set-Cookie
 Header unset Cookie
</FilesMatch>

<IfModule mod_expires.c>
 FileETag MTime

 ExpiresActive on
 ExpiresDefault "access plus 28 days"

 ExpiresByType text/html "access plus 3 hours"

 ExpiresByType application/json "access plus 3 hours"
 ExpiresByType text/xml "access plus 3 hours"
 ExpiresByType application/xml+rss "access plus 3 hours"

 ExpiresByType text/css "access plus 7 days"

 ExpiresByType text/javascript "access plus 14 days"
 ExpiresByType application/x-javascript "access plus 14 days"
 ExpiresByType application/javascript "access plus 14 days"

 ExpiresByType text/plain "access plus 28 days"

 ExpiresByType image/x-icon "access plus 28 days"
 ExpiresByType image/jpeg "access plus 28 days"
 ExpiresByType image/png "access plus 28 days"
 ExpiresByType image/gif "access plus 28 days"

 ExpiresByType application/x-shockwave-flash "access plus 28 days"

 ExpiresByType application/x-font-ttf "access plus 1 years"
 ExpiresByType application/x-font-opentype "access plus 1 years"
 ExpiresByType application/x-font-woff "access plus 1 years"
 ExpiresByType application/x-font-woff2 "access plus 1 years"
 ExpiresByType application/vnd.ms-fontobject "access plus 1 years"
 ExpiresByType image/svg+xml "access plus 1 years"

 ExpiresByType text/x-component "access plus 1 years"
</IfModule>

<IfModule mod_deflate.c>
 AddOutputFilterByType DEFLATE text/html
 AddOutputFilterByType DEFLATE text/plain

 AddOutputFilterByType DEFLATE application/json
 AddOutputFilterByType DEFLATE text/xml
 AddOutputFilterByType DEFLATE application/xml+rss

 AddOutputFilterByType DEFLATE text/css

 AddOutputFilterByType DEFLATE text/javascript
 AddOutputFilterByType DEFLATE application/x-javascript
 AddOutputFilterByType DEFLATE application/javascript

 AddOutputFilterByType DEFLATE application/x-shockwave-flash

 AddOutputFilterByType DEFLATE application/x-font-ttf
 AddOutputFilterByType DEFLATE application/x-font-opentype
 AddOutputFilterByType DEFLATE application/x-font-woff
 AddOutputFilterByType DEFLATE application/x-font-woff2
 AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
 AddOutputFilterByType DEFLATE image/svg+xml

 AddOutputFilterByType DEFLATE text/x-component

 # Remove browser bugs (only needed for really old browsers)
 BrowserMatch ^Mozilla/4 gzip-only-text/html
 BrowserMatch ^Mozilla/4\.0[678] no-gzip
 BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
 Header append Vary User-Agent
</IfModule>

  • wp-config.php optimization, modification of cron task calling time:

define('WP_CRON_LOCK_TIMEOUT', 600);

IV. Database optimization

I empty the recycle bin, automatic drafts, spam and old data, optimize database tables. What takes up most space is entries versions, that’s why it’s a good practice to limit their number to 100.

  • WP-Optimize,
  • wp-config.php optimization, modification of the frequency of auto-saving entries and limiting the number of versions:

define('AUTOSAVE_INTERVAL',3600);
define('WP_POST_REVISIONS',100);

V. Security

First of all, when installing WordPress, you should give a database name other than default. Also, you shouldn’t use a default login for administrator name, like “admin” or “administrator”. If you post on a website, you shouldn’t use administrator’s account for posting articles or commenting, and a nickname should be other than the user’s name. This way you will avoid many attacks that will attempt to get your password by brute force.

  • Wordfence Security, protection against basic attacks and viruses,
  • Loginizer, login protection / anti brute force,
  • PHP security:

function sr_security() {
  global $user_ID;

  if ($user_ID) {
    if ( !current_user_can('manage_options') ) {
      if (strlen($_SERVER['REQUEST_URI']) > 255 ||
          stripos($_SERVER['REQUEST_URI'], "eval(") ||
          stripos($_SERVER['REQUEST_URI'], "CONCAT") ||
          stripos($_SERVER['REQUEST_URI'], "UNION+SELECT") ||
          stripos($_SERVER['REQUEST_URI'], "base64")) {
        if (!headers_sent()) {
          header("HTTP/1.1 414 Request-URI Too Long");
          header("Status: 414 Request-URI Too Long");
          header("Connection: Close");
        }
        exit;
      }
    }
  }
}
add_action( 'init', 'sr_security' );

  • .htaccess security, blocking author search, 5G BLACKLIST/FIREWALL:

RewriteCond %{QUERY_STRING} author=
RewriteRule .* empty [R=404,L]

# 5G BLACKLIST/FIREWALL
# @ http://perishablepress.com/5g-blacklist/

# 5G:[QUERY STRINGS]
<ifModule mod_rewrite.c>
 RewriteCond %{QUERY_STRING} (environ|localhost|mosconfig|scanner) [NC,OR]
 RewriteCond %{QUERY_STRING} (mod)\=\.?/? [NC,OR]
 RewriteCond %{QUERY_STRING} boot\.ini  [NC,OR]
 RewriteCond %{QUERY_STRING} echo.*kae  [NC,OR]
 RewriteCond %{QUERY_STRING} etc/passwd [NC,OR]
 RewriteCond %{QUERY_STRING} \=\\%27$   [NC,OR]
 RewriteCond %{QUERY_STRING} \=\\\'$    [NC,OR]
 RewriteCond %{QUERY_STRING} \.\./      [NC,OR]
 RewriteCond %{QUERY_STRING} \?         [NC]
 RewriteRule .* - [F]
</ifModule>

# 5G:[USER AGENTS]
<ifModule mod_setenvif.c>
 SetEnvIfNoCase User-Agent (casper|cmsworldmap|diavol|dotbot)   keep_out
 SetEnvIfNoCase User-Agent (flicky|ia_archiver|jakarta|kmccrew) keep_out
 SetEnvIfNoCase User-Agent (libwww|planetwork|pycurl|skygrid)   keep_out
 SetEnvIfNoCase User-Agent (purebot|comodo|feedfinder|turnit)   keep_out
 SetEnvIfNoCase User-Agent (zmeu|nutch|vikspider|binlar|sucker) keep_out
 <limit GET POST PUT>
  Order Allow,Deny
  Allow from all
  Deny from env=keep_out
 </limit>
</ifModule>

# 5G:[REQUEST STRINGS]
<ifModule mod_alias.c>
 RedirectMatch 403 (https?|ftp|php)\://
 RedirectMatch 403 /(cgi|https?|ima|ucp)/
 RedirectMatch 403 /(Permanent|Better)$
 RedirectMatch 403 (\=\\\'|\=\\%27|/\\\'/?|\)\.css\()$
 RedirectMatch 403 \.(cgi|asp|aspx|cfg|dll|exe|jsp|mdb|sql|ini|rar)$
 RedirectMatch 403 /(contac|fpw|install|pingserver|register)\.php$
 RedirectMatch 403 (base64|crossdomain|localhost|wwwroot|e107\_)
 RedirectMatch 403 (eval\(|\_vti\_|\(null\)|echo.*kae|config\.xml)
 RedirectMatch 403 \.well\-known/host\-meta
 RedirectMatch 403 /function\.array\-rand
 RedirectMatch 403 \)\;\$\(this\)\.html\(
 RedirectMatch 403 proc/self/environ
 RedirectMatch 403 msnbot\.htm\)\.\_
 RedirectMatch 403 /ref\.outcontrol
 RedirectMatch 403 com\_cropimage
 RedirectMatch 403 indonesia\.htm
 RedirectMatch 403 \{\$itemURL\}
 RedirectMatch 403 function\(\)
 RedirectMatch 403 labels\.rdf
 RedirectMatch 403 /playing.php
 RedirectMatch 403 muieblackcat
</ifModule>

# 5G:[BAD IPS]
<limit GET POST PUT>
 Order Allow,Deny
 Allow from all
 # uncomment/edit/repeat next line to block IPs
 # Deny from 123.456.789
</limit>

# 5G:[WordPress]
<ifModule mod_rewrite.c>
 RedirectMatch 403 /\$\&
 RedirectMatch 403 (?i)/\&(t|title)=
 RedirectMatch 403 (?i)/\.(bash|git|hg|log|svn|swp|tar)
 RedirectMatch 403 (?i)/(1|contact|i|index1|iprober|phpinfo|phpspy|product|signup|t|test|tz|visit|webshell|wp-signup).php
 RedirectMatch 403 (?i)/(author-panel|class|database|manage|phpMyAdmin|register|submit-articles|system|usage|webmaster)/?$
 RedirectMatch 403 (?i)/(=|_mm|cgi|cvs|dbscripts|jsp|rnd|userfiles)
</ifModule>

  • wp-config.php security, disabling file editing in WordPress:

define('DISALLOW_FILE_EDIT',true);

WordPress is often used as SEO catalogue, so every user is a potential target of spammer attack. You shouldn’t leave any forms unsecured, otherwise you will be bombarded with tons of automatically generated comments and e-mails.

  • Akismet, protection against spam,
  • security a form:

.DISABLE{display:none}

<input name="sr-code" value="ąćęłńóśżź" type="hidden" />
<input class="DISABLE" name="submit" value="spam" type="submit" />
<input name="submit" value="Wyślij" type="submit" />

 if (($_POST['submit']==='spam') || ($_POST['sr-code']!=='ąćęłńóśżź')) die();


Clients

  • play
  • plk
  • pkp-cargo
  • uniwersytet-warszawski
  • politechnika-poznanska
  • uniwersytet-adama-mickiewicza
  • termy-maltanskie
  • rzeczpospolita
  • v33
  • ferguson
  • unitra
  • wyzsza-szkola-urody-i-edukacji
  • wyzsza-szkola-handlu-i-uslug