WPmagus - magicy od WordPressa

Wyczaruj sobie spokój

Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl

Dlaczego atakować?

  • 58.8% spośród CMSów to WordPress
    (10 września 2015, w3techs.com)
  • 8 804 tys. pobrań WP 4.3
    (10 września 2015, wordpress.org/download/counter)

Po co atakować?

  • spamerskie linki
  • przekierowania
  • rozsyłanie spamu
  • ataki DDoS
  • zarażanie innych
  • itd.

Ataki są częste

(https://sucuri.net/security-reports/brute-force/)

Zacznij od hostingu

41% ataków na WordPress udaje się dzięki luce zabezpieczeń hostingu
(wpwhitesecurity.com)

Jaki wybrać?

Przy wyborze warto zadać sobie te pytania:

  • Jakie ma opinie obecnych użytkowników?
  • Czy support jest dostępny?
  • Jakiej wersji PHP używa?
  • Jaką ma politykę backupów?
  • Czy zapewnia separację różnych domen?
  • Czy zapewnia mechanizm blokujący ataki DDoS?
  • Czy umożliwia łączenie SFTP?

Tego dopilnuj sam

Pewnych rzeczy hosting za nas nie zrobi. Zakładając konto koniecznie:

  • nie ułatwiaj zgadnięcia loginu (inny niż domena)
  • ustaw mocne hasło dla konta w hostingu

Utrzymuj porządek

Im większy bałagan na serwerze, tym łatwiej na nim ukryć malware. Kilka prostych zasad:

  • Osobna baza dla każdej strony
  • Każda strona z separacją
  • Wymyśl strukturę katalogów
  • Nie traktuj serwera jako przechowalni plików

Mamy hosting instalujemy WP

Nie używaj autoinstalatorów

Są wygodne, ale:

  • chcesz się wyróżnić, a nie upodobnić
  • chcesz mieć pewność co do plików instalacji
  • chcesz mieć kontrolę

Tworząc bazę danych…

  • stwórz osobną bazę dla każdej strony
  • najlepiej bez dostępu zdalnego
  • w której db_name != db_user
  • z mocnym hasłem

A instalując WordPressa…

  • wymyśl trudny prefiks tabel
  • wybierz unikalną nazwę użytkownika (nie admin!)
  • i ustaw mu mocne hasło

Potem dbaj o higienę

Aktualizuj WP…

(https://wordpress.org/about/stats/)

… oraz wtyczki i motywy

Ataki na WordPressy kończą się sukcesem dzięki:

  • 29% - podatnościom motywu
  • 22% - podatnościom wtyczek

(wpwhitesecurity.com)

Uważaj co i skąd pobierasz

Pobranie płatnego motywu za darmo może być kuszące, ale może być bardzo kosztowne.

  • Motywy i wtyczki instaluj tylko z zaufanych źródeł…
  • … bo nie masz żadnej pewności (ani gwarancji), co pobierzesz z innego źródła

Zadbaj o backupy

Jeśli chcesz, aby coś było zrobione dobrze, zrób to sam.

Backupuj niezależnie

Wykonuj własne, niezależne backupy:

  • zdalnie lub w chmurze
  • często
  • automatycznie

BackWPup Free, itp.

Zacznijmy zabezpieczać

Klucze to podstawa

W pliku wp-config.php znajdziemy:

define('AUTH_KEY',         '9hZu6i?:b/)?v;]na|TzKx57lR~cOjAy.SCLA?RQ+Qx#X%fX$ ;|&P^L[L4% Nr<');
define('SECURE_AUTH_KEY',  'YCzK7vP{6]SW}K^]iBSIpCa[a7o2h5y$&h2;u,C-U}b 2)Nd?Q~Oz6Taz9;|hwIS');
define('LOGGED_IN_KEY',    'A,M:cKmeUH#t%VT~2!QqN4*KK5`MucN*!UE_i|<nIj,Enr<S0F@P|Kv?9u{_spM;');
define('NONCE_KEY',        '/I%<]LIk5o1KQ]*^CD=8!>M~9AwfG:^}{cpmHy mR%J9*Qeqi4KQ]~xS]rb}Yz(m');
define('AUTH_SALT',        'Yz+A#xDo&D^&-]r!*Ngi`+<vz@~4]#{mcFvl:1V+At#=WG8CN5]Z3CtC#sNZB~52');
define('SECURE_AUTH_SALT', ';):V+|pH~8*AAQirZ0_5e{cO#A$tO%-P-?o^g)ju(Ykp+5|Rx;HkR OSs!aOR[4&');
define('LOGGED_IN_SALT',   '.$2@h.9K|qKe/r5S|-I~%<O]11!?|AygP9$5.&ZS&vanj}9r#;~sqCw{C#>?]sy-');
define('NONCE_SALT',       '6?T^;T/!V?3TX!-M_c~ju;H1/(}]!8/66NAsnFCj^|U-{0vSr>)R.WB!MbD-SMl(');

Wygenerujmy własne:
https://api.wordpress.org/secret-key/1.1/salt/

Przenieś dane bazy

W pliku wp-config.php znajdź:

define('DB_NAME', 'moja_baza');
define('DB_USER', 'moj_user');
define('DB_PASSWORD', 'moje_haslo');
define('DB_HOST', 'moj_host');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

i skopiuj do innego pliku np. wp-config-db.php

a w wp-config.php umieść:

require_once "wp-config-db.php";

Ukryj błędy

To powinien zrobić hosting, ale…

W pliku wp-config.php znajdź:

define('WP_DEBUG', false);

i zamień na:

define('WP_DEBUG', false);

if ( ! WP_DEBUG ) {
	ini_set('display_errors', 0);
}

Wyłącz edytor plików

Wydaje się wygodny, ale i tak nie powinieneś go używać.

W tym samym pliku wp-config.php dopisz poniżej:

define('DISALLOW_FILE_EDIT', true);

Zablokuj dla pewności

Te pliki nigdy nie powinny zostać podejrzane.

W pliku .htaccess dopisz na początku:

<FilesMatch "wp-config.*\.php|\.htaccess|readme\.html">
    Order allow,deny
    Deny from all
</FilesMatch>

Ukryj wersję

Usuń wersję z sekcji head:

remove_action('wp_head', 'wp_generator');

Nie zapomnij o kanałach RSS…:

function my_secure_generator( $generator, $type ) {
	return '';
}
add_filter( 'the_generator', 'my_secure_generator', 10, 2 );

…i plikach w katalogu głównym (poprzedni slajd)

… i w skryptach

function my_remove_src_version( $src ) {
	global $wp_version;

	$version_str = '?ver='.$wp_version;
	$offset = strlen( $src ) - strlen( $version_str );

	if ( $offset >= 0 && strpos($src, $version_str, $offset) !== FALSE )
		return substr( $src, 0, $offset );

	return $src;
}
add_filter( 'script_loader_src', 'my_remove_src_version' );
add_filter( 'style_loader_src', 'my_remove_src_version' );

Zabezpiecz logowanie

W pliku .htaccess w katalogu głównym dodaj:

<Files wp-login.php>
	AuthType Basic
	AuthGroupFile /dev/null
	AuthName "Czego tu szukasz"
	AuthUserFile /sciezka-do-htpasswd/.htpasswd
	require valid-user
</Files>

Jeśli pojawi się pętla przekierowań, to dodaj:

ErrorDocument 401 default

Uwaga: zepsujesz w ten sposób wpisy zabezpieczone hasłem, ale jest sposób i na to.

Także przez XMLRPC

Możesz wyłączyć XMLRPC całkowicie filtrem:

add_filter('xmlrpc_enabled', '__return_false');

lub za pomocą .htaccess:

<Files xmlrpc.php>
	Order deny,allow
	Deny from all
</Files>

Uwaga: XMLRPC czasem się przydaje (pingbacki, aplikacje mobilne, itp.).

Ogranicz wp-admin

W katalogu wp-admin dodaj plik .htaccess:

AuthType Basic
AuthGroupFile /dev/null
AuthName "Czego tu szukasz"
AuthUserFile /sciezka-do-htpasswd/.htpasswd
require valid-user

ale, żeby niczego nie zepsuć, musimy odblokować:

<FilesMatch "admin-ajax\.php|admin-post\.php">
    Order allow,deny
    Allow from all
    Satisfy any
</FilesMatch>

Uwaga: Jeśli nie ograniczasz dostępu do wp-admin, to zablokuj wp-admin/install.php

Chroń loginy użytkowników

Zablokuj typowy sposób enumeracji dodając do .htaccess:

RewriteCond %{QUERY_STRING} author=\d
RewriteRule ^ /? [L,R=301]

Zdradzi Cię wyszukiwarka

Nadal zdradliwe będą wyszukiwarki i sitemapy.

Tworząc użytkowników dbaj, aby
user_login != user_nicename

Wystarczy, że w loginie użyjesz znaków, które nie są dozwolone w URLu, a o resztę zadba sanityzacja WordPressa.

Chroń wp-includes

W katalogu wp-includes dodaj plik .htaccess:

<FilesMatch "\.(?i:php)$">
	Order allow,deny
	Deny from all
</FilesMatch>
<Files wp-tinymce.php>
	Allow from all
</Files>
<Files ms-files.php>
	Allow from all
</Files>

… i wp-content

W szczególności uploads. Dodaj plik .htaccess:

<FilesMatch "\.(?i:php)$">
	Order allow,deny
	Deny from all
</FilesMatch>

Uwaga: Tym możesz zepsuć niektóre wtyczki lub motywy. Choć w takim przypadku warto się zastanowić czy na pewno chcesz z nich korzystać ;)

Co jeszcze warto?

Zabezpieczać można w nieskończoność, ale część zabezpieczeń jest już trudniejsza we wdrożeniu.

  • SSL, przynajmniej dla panelu administracyjnego
  • Podwójna autentykacja (Rublon, Google Authenticator, itp.)

I bardziej dla adminów

I jeszcze rozwiązania dla tych z większym dostępem do serwera:

  • odpowiednie uprawnienia do plików (uwaga: aktualizacje!)
  • monitoring zmian plików (z poziomu serwera)
  • monitoring podejrzanego kodu (nie tylko w plikach *.php)
  • lepsze uprawnienia do plików (szczegóły), ale uwaga, bo to ma swoje skutki uboczne...

Czego nie warto?

Niektórych porad nie warto wdrażać w życie.

  • Nie używaj "kombajnów" do bezpieczeństwa
    • są dziurawe,
    • dają fałszywe poczucie bezpieczeństwa
  • Nie zmieniaj ścieżki wp-admin
    • nie będziesz bezpieczniejszy, bo /admin i /login
    • wp-login i xmlrpc są szybsze niż 404
    • i tak je już zabezpieczyliśmy

Dzięki za uwagę!

Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl