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 -IndexesDomyś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 allJeż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