Bezpieczeństwo
w WordPressie

... czyli jak zapomnieć o atakach na swoją stronę

Metody

obowiązkowe

... które powinny być używane w każdym projekcie

Zmiana prefixu tabel w bazie


    RENAME table `wp_commentmeta` TO `wp_td6y0kv_commentmeta`;
    RENAME table `wp_comments` TO `wp_td6y0kv_comments`;
    RENAME table `wp_links` TO `wp_td6y0kv_links`;
    RENAME table `wp_options` TO `wp_td6y0kv_options`;
    RENAME table `wp_postmeta` TO `wp_td6y0kv_postmeta`;
    RENAME table `wp_posts` TO `wp_td6y0kv_posts`;
    RENAME table `wp_terms` TO `wp_td6y0kv_terms`;
    RENAME table `wp_termmeta` TO `wp_td6y0kv_termmeta`;
    RENAME table `wp_term_relationships` TO `wp_td6y0kv_term_relationships`;
    RENAME table `wp_term_taxonomy` TO `wp_td6y0kv_term_taxonomy`;
    RENAME table `wp_usermeta` TO `wp_td6y0kv_usermeta`;
    RENAME table `wp_users` TO `wp_td6y0kv_users`;

Następnie należy wyszukać i podmienić wyrażenia _wp na nowe:

    
    SELECT * FROM `wp_td6y0kv_options` WHERE `option_name` LIKE '%wp_%'
    SELECT * FROM `wp_td6y0kv_usermeta` WHERE `meta_key` LIKE '%wp_%'

Najlepszym rozwiązaniem jest ustawienie losowego prefixu przy instalacji WP.

Używanie bezpiecznych haseł do logowania, konta FTP i bazy danych

  • małe i duże litery
  • cyfry i znaki specjalne
  • brak wyrażeń słownikowych
  • minimum 8 znaków (zalecane 14)
  • najlepiej używać generatora haseł

Zabezpieczenie pliku

wp-config.php


    <files wp-config.php>
        order allow,deny
        deny from all
    </files>

Plik wp-config.php wymaga największego poziomu zabezpieczenia. Znajduje się w nim bowiem cała konfiguracja bazy danych. Aby zabezpieczyć się przez niepowołanym dostępem do niego należy w pliku .htaccess, w głównym katalogu strony dodać następujący kod:

Zmiana nazwy administratora na randomową nazwę

Nie należy używać nazwy admin, ponieważ ułatwia to hakerom

zalogowanie się do panelu.

Blokada wyszukiwania ID użytkownika


    if (!is_admin() && preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) {

        die();
        add_filter('redirect_canonical', 'shapeSpaceCheckEnumeration', 10, 2);

    }

    function shapeSpaceCheckEnumeration($redirect, $request) {

        if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) {

            die();

        } else {

            return $redirect;

        }

    }

functions.php

Blokada możliwości przeglądania listy katalogów


    Options All -Indexes

Domyślnie wiele serwerów umożliwia przeglądanie listy plików w katalogu, w którym nie ma pliku index. Jest to bardzo niebezpieczne, bo pozwala poznać strukturę strony i pobierać pliki. W celu blokady tego należy w głównym katalogu WordPressa, w pliku .htaccess dodać taki kod:

Ustawienie odpowiednich praw

dla plików i folderów

Najlepszym narzędziem do modyfikacji praw plików i folderów jest klient FTP. Należy ustawić następujące prawa:

  • foldery - 755
  • pliki - 644
  • wp-config.php - 600

Ukrycie wersji WordPressa


	add_filter('script_loader_src', 'removeWPVersionFromIncludedFiles');
	add_filter('style_loader_src',  'removeWPVersionFromIncludedFiles');
	add_filter('the_generator',     '__return_empty_string');

	function removeWPVersionFromIncludedFiles($src) {

		global $wp_version;

		parse_str(parse_url($src, PHP_URL_QUERY), $query);

		if (!empty($query['ver']) && $query['ver'] === $wp_version) {

			$src = remove_query_arg('ver', $src);

		}

		return $src;

	}

functions.php:

Ukrycie nagłówków WordPressa


    remove_action('wp_head',         'rest_output_link_wp_head', 10);
    remove_action('wp_head',         'wp_oembed_add_discovery_links', 10);
    remove_action('wp_head',         'rsd_link');
    remove_action('wp_head',         'feed_links', 2);
    remove_action('wp_head',         'feed_links_extra', 3);
    remove_action('wp_head',         'wlwmanifest_link');
    remove_action('wp_head',         'index_rel_link');
    remove_action('wp_head',         'start_post_rel_link', 10, 0);
    remove_action('wp_head',         'index_rel_link', 10, 0);
    remove_action('wp_head',         'adjacent_posts_rel_link', 10, 0);
    remove_action('wp_head',         'adjacent_posts_rel_link_wp_head', 10, 0);
    remove_action('wp_head',         'wp_shortlink_wp_head');
    remove_action('wp_head',         'print_emoji_detection_script', 7);
    remove_action('wp_print_styles', 'print_emoji_styles');

WordPress domyślnie przekazuje dużo cennych informacji. Można to wyłączyć dodając następujący kod w pliku functions.php:

Powyższy kod może wyłączyć niektóre funkcjonalności WordPressa.

Usunięcie nieużywanych

pluginów i motywów

Każdy plugin oraz motyw to dodatkowy sposób na złamanie zabezpieczeń naszej strony. Poza tym zbędne pluginy obciążają niepotrzebnie naszą stronę. Nie należy przechowywać na serwerze tego, z czego nie korzystamy.

Usunięcie domyślnego wpisu, podstrony, komentarza, oraz zmiana tytułu i opisu strony

Tego typu elementy powstają przy każdej nowej instalacji WordPressa. Pozostawienie ich (przykładowo domyślnego wpisu w sytuacji, gdy na stronie nie mamy bloga) oznacza, że strona jest nowa, co może zachęcić hakera do potencjalnego ataku.

Blokada dostępu do plików z poufnymi informacjami

Na serwerze znajdują się pliki, do których dostęp poprzez protokół HTTP powinien być zablokowany ze względów bezpieczeństwa, ponieważ mogą się w nich znaleźć bardzo poufne informacje. Są to pliki: .htaccess, .htpasswd, *.ini, *.phps, *.fla, *.psd, *.log, *.sh, readme.md, readme.html, license.txt, license.html, install.php, upgrade.php, *.bak, *.git, *.svn, *.sql, *.tar i *.tar.gz. Blokadę dostępu należy dodać do pliku .htaccess.

Wyłączenie trybu

debugowania błędów


    define('WP_DEBUG', false);

wp-config.php

Dodatkowo należy usunąć plik debug.log z katalogu wp-content, ponieważ może on zawierać wiele cennych informacji.

Wyłączenie wyświetlania błędów

w PHP


    error_reporting(0);
    @ini_set('display_errors', 0);

wp-config.php

Metodę tę należy stosować w przypadku posiadania hostingu niższej klasy, który narzuca wyświetlanie błędów, nawet jeśli w WordPressie jest ono wyłączone. Dodatkowo w pliku .htaccess należy dodać regułę: php_flag display_errors off

Blokada edycji plików

motywu i pluginów


    define('DISALLOW_FILE_EDIT', true);

wp-config.php

Powyższy kod można również wrzucić do pliku functions.php, i także będzie

to działać.

Automatyczna aktualizacja

WordPressa


    add_filter('auto_update_core', '__return_true');

funtions.php

Istnieje możliwość zaawansowanego ustawiania aktualizacji, ale lepszym wyborem jest włączenie wszystkich.

Blokada wykonywania plików PHP

w katalogu /wp-content

.htaccess (w katalogu /wp-content)


    <Files *.php>
        deny from all
    </Files>

Zabezpieczenie katalogu

/wp-includes


    <IfModule mod_rewrite.c>
        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]
    </IfModule>

Aby zabezpieczyć ten folder należy utworzyć w nim następujący plik .htaccess:

Blokada dostępu do katalogów

przez roboty


    User-agent: *
    Disallow: /wp-admin/
    Disallow: /wp-includes/
    Disallow: /wp-content/languages/
    Disallow: /wp-content/plugins/
    Disallow: /wp-content/themes/
    Disallow: /wp-content/upgrade/
    Disallow: /*?*
    Disallow: *?replytocom
    Disallow: /archives/
    Disallow: /comments/feed/

W celu zabezpieczenia katalogów przed indeksowaniem ich przez roboty należy w głównym katalogu utworzyć plik robots.txt o następującej treści:

Blokada HTTP TRACE i TRACK


    RewriteEngine on
    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
    RewriteRule .* - [F]

Technologie te są używane w większości serwerów Apache do debugowania. Przez hakerów jest to wykorzystywane do pewnych ataków Cross Site Tracing (XST) i Cross Site Scripting (XSS). Można temu łatwo zapobiec dodając do głównego pliku .htaccess taki kod:

Wyłączenie REST API


    add_filter('rest_api_init', 'disableRestAPI');

    function disableRestAPI() {

        die();

    }

REST API umożliwia odczytywanie publicznych treści przez zewnętrzne aplikacje oraz ich modyfikację i dodawanie nowych, jeżeli dokonana zostanie autoryzacja. W większości stron nie jest to potrzebne. W celu blokady REST API należy w pliku functions.php umieścić poniższy kod:

Blokada dostępu do XML-RPC


    <files xmlrpc.php>
	order allow,deny
	deny from all
    </files>

Plik xmlrpc.php używany jest przez zewnętrzne aplikacje do zarządzania WordPressem. Bardzo rzadko używa się tej funkcjonalności, a przez hakerów używana jest ona do ataków typu Brute Force. Aby im zapobiec wystarczy do pliku .htaccess w głównym katalogu WordPressa dodać taki kod:

Blokada infekcji przez URL


    if (!is_user_logged_in() || !current_user_can('administrator')) {
    
    	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")) {
    
    			@header("HTTP/1.1 414 Request-URI Too Long");
    			@header("Status: 414 Request-URI Too Long");
    			@header("Connection: Close");
    			@exit;
    
    	}

    }

funtions.php

Powyższy kod może blokować niektóre pluginy lub własne funkcje.

Korzystanie z

rekomendowanego hostingu

Oszczędność nie zawsze się opłaca. Profesjonalne hostingi posiadają więcej zabezpieczeń utrudniających potencjalne ataki. Nie ma większego sensu zabezpieczać witryny, jeśli hosting nie jest bezpieczny, ponieważ udany atak na nasz serwer FTP albo bazę danych pozwoli na pełny dostęp do serwisu.

Regularne kopie

bezpieczeństwa

Nigdy nie mamy 100% poziomu bezpieczeństwa, dlatego regularne kopie bezpieczeństwa są koniecznością. Istnieje wiele pluginów, które robią to automatycznie. Można również wykupić specjalne hosting z wbudowaną narzędziem do wykonywania kopii całego FTP i bazy danych.

Dbaj o swój kod ;)

Tworząc bardziej skomplikowane strony często piszemy dużo własnego kodu, różnego rodzaju formularze i mniejsze lub większe API. Tutaj warto zwrócić szczególną uwagę na walidację przesyłanych przez użytkowników danych, a także wszelkiego typu "nieprzemyślane akcje". To, że zaplanowałeś jakieś działanie nie oznacza, że ktoś zrobi to tak, jak Ty myślisz - a wszelkie możliwe wyjątki należy odpowiednio obsłużyć.

Metody

zaawansowane

... do użycia w projektach o podwyższonym poziomie bezpieczeństwa

Instalacja wtyczki

bezpieczeństwa

Do wyboru jest wiele narzędzi, ale najbardziej cenione są iThemes Security oraz Wordfence. W sieci można znaleźć wiele poradników dotyczących ich poprawnej konfiguracji. Aby uzyskać maksymalny poziom bezpieczeństwa warto wykupić wersję płatną pluginu, która zawiera wszystkie funkcje.

Generowanie nowych kluczy autoryzacyjnych


    define('AUTH_KEY',         '');
    define('SECURE_AUTH_KEY',  '');
    define('LOGGED_IN_KEY',    '');
    define('NONCE_KEY',        '');
    define('AUTH_SALT',        '');
    define('SECURE_AUTH_SALT', '');
    define('LOGGED_IN_SALT',   '');
    define('NONCE_SALT',       '');

wp-config.php

Operację należy wykonać przy wdrożeniu strony na serwer docelowy. W tym pliku znajdziemy link do generatora kluczy.

Ukrycie nazwy administratora

Domyślnie WordPress tworzy strony z postami danego użytkownika, dzięki czemu można "wytropić" jego nazwę. Aby to zmienić należy:

  • wejść do bazy danych
  • znaleźć w tablicy wp_users konto administratora
  • zmienić wartość w kolumnie user_nicename na inną niż w user_login

Automatyczna aktualizacja

pluginów


    add_filter('auto_update_plugin', '__return_true');

funtions.php

Używając tej opcji należy instalować tylko sprawdzone pluginy albo użyć funkcji pozwalającej wybrać pluginy, które mają się same aktualizować.

Blokada dostępu

do katalogu /wp-content

.htaccess (w katalogu /wp-content)


    Order Allow,Deny
    Deny from all
    <files ?.(jpg|gif|png|js|css)$? ~>
    Allow from all

Jeżeli używasz innego typu plików multimedialnych dodaj je w powyższym kodzie.

Ukrycie domyślnych adresów logowania

Jedynym sposobem na zalogowanie się jest znajomość konkretnego adresu URL, ponieważ wszystkie domyślne są zablokowane.

Warto ukryć domyślne adresy logowania. Najlepszym narzędziem do tego celu jest plugin WPS Hide Login, który blokuje także przekierowanie na podstronę logowania po wejściu na adres /wp-admin.

Limit nieudanych

zalogowań

Hakerzy często stosują brutalne metody ataku polegające na wielokrotnym wpisywania danych, aż do skutku. Przy użyciu pluginu, np. Login LockDown można w łatwy sposób określić limit nieudanych prób logowania, który uniemożliwi tego typu ataki.

Wyłączanie możliwości logowania

za pomocą adresu e-mail


    remove_filter('authenticate', 'wp_authenticate_email_password', 20);

Używając losowej nazwy użytkownika i jednocześnie pozwalając na logowania poprzez podania adresu e-mail mocno zmniejszamy poziom bezpieczeństwa, ponieważ e-mail można zdobyć dużo łatwiej niż losową nazwę.

funtions.php

Automatyczne wylogowania

po czasie bezczynności

Nie zawsze ataki są dokonywane z zewnątrz. Czasami wystarczy się nie wylogować, aby ktoś "sympatyczny" dostał się do naszej strony. Różne wtyczki, np. Idle User Logout pozwalają ustawić czas bezczynności, po którym nastąpi automatyczne wylogowania użytkownika.

Blokada resetowania

hasła


    add_filter('allow_password_reset', '__return_false');

Tymczasową blokadę resetowania hasła można w każdej chwili zdjąć na czas przywracania hasła, a dzięki niej nawet dostęp do naszej skrzynki mailowej uniemożliwi dostęp do strony.

funtions.php

Dodatkowe zabezpieczenie katalogu /wp-admin hasłem

Aby ustawić dodatkowe hasło do panelu administracyjnego należy utworzyć w nim pliki .htaccess i .htpasswd (najlepiej jest tutaj skorzystać z generatora online). Pamiętaj o wyjątku w .htaccess dla pliku admin-ajax.php:


    <Files admin-ajax.php>
    	Order allow,deny
    	Allow from all
    	Satisfy any 
    </Files>

Przeniesie pliku wp-config.php


    if (!defined('ABSPATH'))
        define('ABSPATH', dirname(__FILE__) . '/');
    
    /* Location of your WordPress configuration. */
    
    require_once(ABSPATH . '../phpdocs/wp-config.php');

Po przeniesieniu pliku wp-config.php w inne miejsce na serwerze w starym pliku wklej następujący kod:

Pamiętaj o zabezpieczeniu nowego pliku specjalnym plikiem .htaccess.

Hosting z certyfikatem SSL

Certyfikat SSL pozwala zabezpieczyć stronę internetową szyfrując dane przesyłane pomiędzy użytkownikiem. Korzystanie z niego jest wręcz wymagane w przypadku uwierzytelniania użytkowników, przesyłania poufnych danych osobowych oraz wszelkiego rodzaju płatności. Bez niego haker może np. przechwycić Twoje dane do panelu administracyjnego. A dodatkowo SSL pozytywnie na SEO i zwiększa zaufanie do witryny, co pomaga budować markę ;)

Wymóg korzysta z SSL podczas logowania i w panelu admina


    define('FORCE_SSL_ADMIN', true);
    define('FORCE_SSL_LOGIN', true);

wp-config.php

Metodę tę należy stosować rzecz jasna, jeśli posiada certyfikat SSL dla naszej strony.

Osobne konto FTP

w przypadku wielu stron

Posiadanie kilku serwisów na jednym hostingu zdecydowanie zmniejsza bezpieczeństwo, ponieważ udany atak na jedną ze stron może spowodować zmianę plików na pozostałych. Podczas konfiguracji hostingu należy dla każdej z nich utworzyć osobne konto FTP, dzięki czemu odseparujemy je od siebie.

Dziękuję

za uwagę :)

Przygotował: Mateusz Gbiorczyk

© Crafton 2017

Bezpieczeństwo w WordPressie

By Mateusz Gbiorczyk

Bezpieczeństwo w WordPressie

  • 345