Best practice per un Wor(l)dPress migliore

CONSIGLI DI BUON SENSO E TRUCCHI



La sicurezza è l'attenzione ai dettagli.

#1 - SERVER

Dietro un grand'uomo c'è sempre una grande donna...

Dietro un sito sicuro c'è sempre un server sicuro!

  • utilizzo di iptables
  • utilizzo dell'SFTP
  • usare modulo di apache: ModSecurity
  • backup server-side DB e Filesystem
  • script a crontab per controllo di file e versioni
  • sistemi di monitoring (Munin, Nagios)


#2 - VERSIONs

Mostrare le versioni del software
che si utilizza è la prima falla di sicurezza.

  • apache
  • php
  • Wordpress
  • JS

#3 - FILEs 'n' DIRs

Apache: 

<files wp-config.php>
order allow,deny
deny from all
</files>
wp-config.php
define('DISALLOW_FILE_EDIT', true);

Directories:

find /path/to/your/wordpress/install/ -type d -exec chmod 755 {} \;

Files:

find /path/to/your/wordpress/install/ -name 'wp-config.php' -exec chmod 440 {} \;
find /path/to/your/wordpress/install/ -type f -exec chmod 644 {} \;

#4 - Script

Uno script a crontab può agilmente:
  • cancellare il file /wp-admin/install.php
  • controllare le permissions
  • verificare la versione di Wordpress
  • riportare tutti i file modificati

Oltre il 70% delle installazioni di Wordpress

sono vulnerabili per mancati aggiornamenti.

#5 - DATABASE

  • Il table_prefix può essere variato a piacimento.
  • La porta di connessione a MySQL può essere cambiata e gestita durante la connessione come segue:
define('DB_HOST', 'localhost:1234');
  • Le permission per un utilizzo standard possono essere:
    SELECT, INSERT, UPDATE and DELETE Per aggiornamenti e installazioni di Wordpress e/o plugins sono necessari tutti i privilegi.
  • Per evitare che le dimensioni del DB crescano  a dismisura è buona prassi importare nel wp-config come segue:
define('WP_POST_REVISIONS', 2); // any integer, but don't get too crazy
// define('WP_POST_REVISIONS', false);
  • Si può tracciare il numero delle query e le query stesse e eventualmente controllarle e riscriverle
  • E' buona usanza usare la cache di MySQL

#6 - Users

  • E' buona prassi che non esista lo user "admin". 
    Se esiste, si può creare un altro user amministratore e cancellare il precedente "admin".
  • Le password per essere sicure devono essere complesse
    (esistono tool che aiutano a ricordarle). 
  • Gli id degli user posso essere impostati per partire da una numerazione più alta per essere meno facili da dedurre.
  • Le tabelle di gestione degli user possono essere rinominate e definite come segue:
define('CUSTOM_USER_TABLE', $table_prefix.'my_users');
define('CUSTOM_USER_META_TABLE', $table_prefix.'my_usermeta');

#7 - WP-ADMIN & SSL

Rinominare la cartella è un problema o no? Sì!
Bisogna usare .htpasswd
Dalla versione 3.5 Wordpress supporta SSL per wp-admin:
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
$_SERVER['HTTPS']='on';
Virtual host http:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)\ HTTP/ [NC]
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^/?(wp-admin/|wp-login\.php) https://mysite.com%{REQUEST_URI}%{QUERY_STRING} [R=301,QSA,L]
Virtual host https:
RewriteRule !^/wp-admin/(.*) - [C]
RewriteRule ^/(.*) http://www.mysite.com/$1 [QSA,L]

#8 - wp Version

Per non mostrare la versione Wordpress:

/* Remove links and version */
add_action('init', 'remheadlink');

function remheadlink() {
    remove_action('wp_head', 'rsd_link');
    remove_action('wp_head', 'wlwmanifest_link');
    remove_action('wp_head', 'wp_generator'); // remove wp versions
    remove_action('wp_head', 'start_post_rel_link');
    remove_action('wp_head', 'index_rel_link');
    remove_action('wp_head', 'adjacent_posts_rel_link');
} 

#9 - CHIAVI

Chiavi univoche di identificazione

define('AUTH_KEY',         '~*+7U?+I!{rmDXf8@Tre0%4_9vYB^z1W^$X}!|niFs#p*`Hxloj6!Vi-IUANSu&l');
define('SECURE_AUTH_KEY',  '>)`fA[fW~)ra:nm<XLp`,$%y[:XHO$]M<X#.]tUh.&|DphKQtM2e3q6gO2+aVjF<');
define('LOGGED_IN_KEY',    'xw8ER`;Jgm{wJg2>i&A:kz:ya[-z+p SWVH{chgF-@kw$>_!5n*d7{a!{*XD$-!c');
define('NONCE_KEY',        'A}AO+49yjT!R|NsM,-<DU;O48Oom&9N7N/u+s)gwTnt).*8j`+Z6Xq|qUarKTJWe');
define('AUTH_SALT',        '|.aIOi}+v;A5[v/Wg?`}ZH|V6gVcFmpP(I)QX4]PT|s)W5#n~5+YdSNDsBMnGi+j');
define('SECURE_AUTH_SALT', 'Fi:M(D!`O$=xC(w>d7D>*!H`I>lT,|p%l{s?P2&1OvMk_h9#GknHOMYA{n-NOsV=');
define('LOGGED_IN_SALT',   'rn5%)xQQ(/v,+8:;_]i1f|M<&HtV}Xa4v<y,dUyR&3xeg-0YKyzssb`k!Djo{wW(');
define('NONCE_SALT',       'h+QSsR{yBoS&/xo~hoxD8O}k5OTx|T3j7HFVcdZvB(Hy],dm&TN/%tonO}6HyDqF');

https://api.wordpress.org/secret-key/1.1/salt/

#10 - CACHE


server side:
Varnish

Wordpress side:
WP Super Cache
W3 Total Cache

THe END


Manuel Kanah
manuel@kanah.it
skype: testinaweb
my_wp: http://www.labna.it


http://slides.com/testinaweb/best-practice-wordpress


Special thanks:
Wordpress, Gabriele Giuranno, Francesco Lentini
Made with Slides.com