Jak zabezpieczyć stronę opartą o system CMS WordPress?

Chciałem zebrać w tym artykule wszystkie możliwe działania jakie można (na nawet trzeba) wykonać aby zabezpieczyć w maksymalnym stopniu swoją stronę opartą o system CMS WordPress. Poniżej przedstawiam w punktach na co należy zwrócić uwagę podczas pierwszej instalacji WordPress-a oraz jak dodatkowo zadbać o jego bezpieczeństwo.

Artykuł ten będzie dla mnie stanowił ‚zbiór działań podstawowych’ z których będę korzystał przy nowych projektach a z drugiej chciałem przy okazji podzielić się tą wiedzą z innymi 😉

1 Instalacja WordPress
1. 1 Unikalna nazwa bazy danych i stosowanie mocnych haseł
1. 2 Wymagane informacje

2 Dodatkowa konfiguracja w pliku /wp-config.php
2. 1 Security Keys – ustawienie kluczy
2. 2 Wyłączenie trybu debugowania
2. 3 Dodatkowe ustawienia w „wp-config.php”

3 WordPress – ustawienie prawa dostępu do folderów i plików
3. 1 Uprawnienia plików i folderów (chmody)
3. 2 Dodatkowe informacje i ew. jeszcze restrykcyjne zmiany

4 Dodatkowe zabezpieczania WordPressa
4. 1 Zabezpieczenie /wp-includes
4. 2 Zabezpieczanie /wp-config.php
4. 3 Zmiana konta administratora i prefixu bazy danych

5 Uwagi po instalacji i moje wątpliwośći
6 O czym należny zawsze pamiętać?

Instalacja WordPress

http://codex.wordpress.org/Editing_wp-config.php

http://www.pctools.com/guides/password/ – przykładowy generator haseł online

1. 1 Unikalna nazwa bazy danych i stosowanie mocnych haseł

  • Przy pierwszej instalacji WordPress-a należy zadbać o to aby nazwa bazy danych, nazwa użytkownika i jego hasło były bezpieczne (trudne do odgadnięcia). Zamiast więc np. bazy o nazwie „dam87_bazawp2013” należy zmienić ją na „dam87_H7@w8a3″, gdzie ‚dam87_” to nazwa loginu w naszym koncie hostingowym na które nie mamy wpływu ale drugi człon którym jest właściwa nazwa bazy danych zmieniamy na bezpieczniejszą wersje. Wszystkie te dane tworzymy w Panelu Administratora naszego serwera a podczas uruchamiania instalacji WordPress-a uzupełniamy tylko te dane w celu połączenia z bazą i uzupełnienia jej przez instalatora
  • Zostaje jeszcze prefix tabeli do zmiany. Sugeruję zmianę jego na unikalny już w tym momencie ponieważ później mogą wyniknąć z tego problemy – przynajmniej ja tak miałem (dlatego nie stosuje wtyczek do zmiany prefixu). Standardowy prefix to „wp_” ale można go zmienić na inny np. „ok_” (pamiętaj aby zawsze dla każdej nowej instalacji strony zmieniać go na unikalny!)

wordpress-zakladanie-bazy
1. 2 Wymagane informacje

  • Po uzupełnieniu danych i nawiązaniu połączenia z baza danych mamy już do wprowadzania „Tytuł witryny” (nie istotne z punktu widzenia bezpieczeństwa)
  • „Nazwa użytkownika” – WP sugeruje „admin” co oczywiście zmieniamy na coś trudniejszego np. „AN1999OK” – wymyśliłem tego użytkownika ‚na szybko’ więc super bezpieczny to on może nie jest ale ważne aby był unikalny i w miarę łatwy do zapamiętania przez nas samych.
  • Co do „Hasło” nie muszę przypominać, że hasło w postaci „admin” lub „admin123” odpada całkowicie! polecam min 8 znaków a najlepiej jeszcze dłuższe i mocno skomplikowanych.
  • Poniżej przytaczam też dwa komunikaty które pojawią się przy uzupełnianiu tych danych, należy je wziąć pod rozwagę:

„Jeśli pozostawisz to pole puste, hasło zostanie automatycznie wygenerowane.”
„Wskazówka: Twoje hasło powinno składać się z co najmniej siedmiu znaków. Aby było ono silniejsze, możesz skorzystać z wielkich i małych liter, cyfr i symboli, takich jak !, „, ?, $, %, ^, & czy ).”

wordpress-instalacja

Dodatkowa konfiguracja w pliku /wp-config.php

2. 1 Security Keys – ustawienie kluczy

  • Cała wcześniejsza konfiguracja zostanie zapisana w pliku „wp-config.php” w katalogu głównym na serwerze gdzie wgrane są wszystkie pliki WordPrssa. Dodatkowo należy zmienić klucze zabezpieczające w tym pliku (najlepiej przy użyciu generatora online. Jeżeli nie masz któregoś z 8 kluczy to stwórz je w tym pliku i uzupełnij o nowo wygenerowane klucze.

https://api.wordpress.org/secret-key/1.1/salt/ (odśwież stronę aby wygenerować nowe klucze)

define(‚AUTH_KEY’, ‚t`DK%X:>xy|e-Z(B2b/f(Ur`8#~UzUQG-^_Cs_GHs5U-&Wb?pgn^p8(2@}IcnCa|’);
define(‚SECURE_AUTH_KEY’, ‚D&ovlU#|CvJ##uNq}2el+^MFtT&.b9{UvR]g%ixsXhGlRJ7q!h}XWdEC[BOKXssj’);
define(‚LOGGED_IN_KEY’, ‚MGKi8Br(&{H*~&0s;{20<S(O:+f#WM+q|npJ-+P;RDKT:~jrmgj#/-,[hOBk!ry^’);
define(‚NONCE_KEY’, ‚FIsAsXJKL5ZlQo)iD-2t??eUbdc{_Cn<4!d~yqz))&B D?AwK%)+)F2aNwI|siOe’);
define(‚AUTH_SALT’, ‚7T-!^i!0,w)L#JK2pc2{8XE[DenYI^BVf{L:jvF,hf}zBf883td6D;Vcy8,S)-&G’);
define(‚SECURE_AUTH_SALT’, ‚I6`V|mDZq21-J|2hb u^q0F }F_NUcy`l,=obGtq*p#Ybe4a31R,r=|n#=]@]c #’);
define(‚LOGGED_IN_SALT’, ‚w<$4c$Hmd%/*]`2om>(hdXW|0M=X={we6;Mpvtg+V.o<$|#_}qG(GaVDEsn,~*4i’);
define(‚NONCE_SALT’, ‚a|#h{c5|P &xWs2IZ20c2&%4!c(/uG}W:mAvy<I44`jAbup]t=]V<`}.py(wTP%%’);
– przykładowe wygenerowane klucze (nie korzystaj z nich!)

2. 2 Wyłączenie trybu debugowania

  • Może się zdarzyć sytuacja w której strona się po prosu w którymś momencie ‚wysypie – uruchomi z błędami’.
  • Wtedy błędy zostaną wyświetlone bezpośrednio na stronie ujawniając w ten sposób np. ścieżkę instalacji WordPressa lub inne dane które mogą być pomocne intruzowi w ataku na naszą stronę.
  • Oczywiście chcemy tego uniknąć więc można wyłączyć „tryb debugowania” wstawiając w pliku wp-config.php kod:

define(‚WP_DEBUG’, false);
oraz dla skryptów
define(‚SCRIPT_DEBUG’, false);
define(‚CONCATENATE_SCRIPTS’, false);

  • Ma to też swój minus w postaci takiej, że jeżeli my będziemy wprowadzać jakieś zmiany na stronie i strona nam się „wykrzaczy” to nie zobaczymy szczegółów błędu – więc trudniej będzie nam go zlokalizować i poprawić. Więc można tryb ten wprowadzić dopiero na samym końcu wszystkich ustawiań. Więcej ustawień w CODEX-ie WodPressa http://codex.wordpress.org/Editing_wp-config.php

2. 3 Dodatkowe ustawienia w „wp-config.php”

  • Można dodatkowo usunąć możliwość bezpośredniego edytowania szablonu w panelu administratora (po zalogowaniu do WordPressa). Zabezpieczymy się w ten sposób przed ewentualnością przejęcia konta użytkownika przez osobę postronną stosując kod:

define(‚DISALLOW_FILE_EDIT’,true);

  • Ustawienie tej regułki spowoduje wyłącznie funkcji edycji plików (dla wszystkich użytkowników):
  • „Placing this line in wp-config.php is equivalent to removing the ‚edit_themes’, ‚edit_plugins’ and ‚edit_files’ capabilities of all users” „This will not prevent an attacker from uploading malicious files to your site, but might stop some attacks.” – Nie uniemożliwia napastnikowi wysyłania złośliwych plików na twojej stronie, ale może zatrzymać niektóre ataki.
  • Więcej dodatkowych możliwości takich jak wymuszenie logowania na konto administratora przez SSL czy wyłącznie powiadamiań i możliwość instalacji wtyczek i stylu szablonu przez zwykłego użytkownika znajdziesz na stronach CODEX-u WP np. tu: http://codex.wordpress.org/Administration_Over_SSL

WordPress – ustawienie prawa dostępu do folderów i plików

Teraz należy upewnić się czy prawa dostępu do plików i folderów na serwerze są odpowiednie. Bo przecież nie chcemy np. aby ktoś mógł zobaczyć zawartość samego pliku /wp-config.php zawierającego wcześniej zdefiniowane przez nas dane dostępowe (nazwę bazu, login i hasło) 😉

http://codex.wordpress.org/Changing_File_Permissions

3. 1 Uprawnienia plików i folderów (chmody)

777 – Wszyscy mają pełne prawa (nie zalecane)
755 – Właściciel ma wszystkie prawa do pliku, reszta tylko prawo do odczytu i uruchomienia
640 – Właściciel ma prawo do zapisu i odczytu, a reszta tylko prawo odczytu
600 – Tylko właściciel ma prawo do odczytu i zapisu

  • wszystkie katalogi powinny być 755 lub 750 (Nie nadawać! praw katalogom 777)
  • wszystkie pliki powinny być 644 lub 640 (wyjątek: wp-config.php powinno być 600)

(tutaj wstawię jak tylko znajdę zalecane przeze mnie ustawiania, żebym ja ani ty w przyszłości nie zastanawiał się ‚co i jak’)

  • Domyślne uprawnienia:

644 -rw-r–r– /home/user/wp-config.php
644 -rw-r–r– /home/user/cgi-bin/.htaccess
644 -rw-r–r– /home/user/cgi-bin/php.ini
755 -rwxr-xr-x /home/user/cgi-bin/php.cgi
755 -rwxr-xr-x /home/user/cgi-bin/php5.cgi

  • Bezpieczne uprawnienia:

600 -rw——- /home/user/wp-config.php
604 -rw—-r– /home/user/cgi-bin/.htaccess
600 -rw——- /home/user/cgi-bin/php.ini
711 -rwx–x–x /home/user/cgi-bin/php.cgi
100 —x—— /home/user/cgi-bin/php5.cgi

3. 2 Dodatkowe informacje i ew. jeszcze restrykcyjne zmiany

.htaccess
644 > 604 – Zmiana z 644 na 604 (można zmienić dla większego bezpieczeństwa, jednak może zdążyć się sytuacja w której strona główna i podstrony nie będą się wczytywać lub niektóre wtyczki które korzystają z dostępu do htacces-a też będą nie działać w sposób prawidłowy. Dlatego jeżeli nie wie się jakie uprawnia nadać – można na początku metodą prób i błędów wybadać zachowanie systemu CMS i dokonać ‚najlepszego wyboru’)

php.ini
644 > 600 – Trudno mi się odnieść do tego przypadku narazie. Jednak z samego tłumaczenia strony z języka angielskiego wynika, że w zależności jakie prawa ma ustawiony użytkownik w systemie z takimi może wywołać ten plik – więc wychodzi na to, że dla większego bezpieczeństwa można zmniejszyć mu prawa dostępu.

php.cgi
755 > 711 – Tłumaczenie wygląda mniej więcej tak „Ten plik jest skompilowany php-cgi binarne zamiast mod_php lub domyślnego waniliowym php dostarczonych przez firmy hostingowej. Domyślne uprawnienia dla tego pliku jest 755” i nie będę tego szerzej opisywał.

php5.cgi
755 > 100 – Tu też nie będę próbował tłumaczyć tylko wkleję regułkę ze strony:

„Because of the setup where the user account is the owner of the process running the php cgi, no other user or group needs access, so we disable all access except execution access. This is interesting because it really works. You can try reading the file, writing to the file, etc.. but the only access you have to this file is to run php scripts. And as the owner of the file you can always change the permission modes back again.”

wp-config.php
644 > 600 a nawet na 640, 440, 400 – Wszystkie te ustawienia wywnioskowałem podczas czytania punku opisanego w CODEX-ie: „Also, make sure that only you (and the web server) can read this file (it generally means a 400 or 440 permission)”

Uwaga!

  • Niektóre wtyczki wymagają dostępu całego folderu /wp-content/ (ustawienie chmod 755) w takim przypadku będą nas o tym informować podczas ich instalacji.
  • Tak samo może się zdarzyć z dostępem w przypadku katalogów /wp-content/cache/ oraz /wp-content/uploads/, więc jeżeli będziesz miał problemy jakieś np. z instalacją wtyczek to sprawdź te dostępy.

Dodatkowe zabezpieczania WordPressa

4. 1 Zabezpieczenie /wp-includes
http://codex.wordpress.org/Hardening_WordPress

  • Metoda nie testowana przeze mnie jeszcze z uwagi na ewentualne problemy. Generalnie chodzi tu chyba o to, że blokujemy includowanie (dodawanie) do strony przy jej generowaniu wszystkich dodatkowych skryptów samych (ale nie samych wtyczek!) wtyczek.
  • Wiadomo, że każdy skrypt wtyczki może nie być do końca przemyślany i dobrze napisany (i tym samym do końca bezpieczny). A przez to może dawać pośrednią możliwość ‚wstrzyknięcia’ innego złośliwego kodu.
  • Aby to zrobić należy w pliku .htacces umieścić dodatkowe regułki:

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]

4. 2 Zabezpieczanie /wp-config.php

A) Przeniesienie pliku wp-config.php

  • Nie dawno trafiłem na to rozwiązanie i wydaje się być ono jednym ze standardowych działań jakie należy robić przy instalacji ‚świeżej’ wersji WordPressa
  • Normalnie plik z całą konfiguracją WP jest zapisywany w pliku wp-config.php.
  • Możemy co prawda zmniejszyć uprawnia jego odczytu i modyfikacji ale możemy również zmienić jego standardową lokalizację przenosząc go ‚o poziom wyżej’ w strukturze plików – wtedy nikt go nie będzie mógł odczytać (tylko my przez bezpośredni dostęp do serwera)

wordpress-przeniesienie-wpconfig

Hmmm.. i od razu notatka „Some people assert that moving wp-config.php has minimal security benefits and, if not done carefully, may actually introduce serious vulnerabilities. Others disagree.”

Jak zawsze wniosek nasuawa się jeden – ‚przy zdrowym podejściu’ do tematu, jeżeli zrobisz to właściwie to na pewno podniesiesz poziom bezpieczeństwa twojej strony a jeżeli nie i powstaną nie dociągnięcia (dodatkowe luki) które umożliwią atak – twoja decyzja!?
Jak to zrobić poprawnie? Poszukaj w sieci 😉

B) Całkowite zablokowanie edycji pliku wp-config.php

  • Blokujemy edycje całkowicie pliki, uwaga jak zawsze – mogą pojawiać się problemy!
  • Umieść w .htaccesie na samej gorze regułki:

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

4. 3 Zmiana konta administratora i prefixu bazy danych

  • Najlepiej (jak to pisałem wcześniej) zająć się tym podczas pierwszej instalacji WordPressa, ale można zmienić te dane przy pomocy komend MySQL lub instalując odpowiednie wtyczki (zalecam przy tym działaniu schemat postępowania – zainstalowanie wtyczki, dokonanie zmian i usuniecie wtyczki).
  • Polecenie MySQL zmieniające domyślą nazwę ‚admin’ na ‚nasza nazwę użytkownika’:
  • UPDATE wp_users SET user_login = ‚newuser’ WHERE user_login = ‚admin’;

Uwagi po instalacji i moje wątpliwości

1. Gdy odpalamy instalację WordPressa na pierwszym ekranie po naciśnięciu „Utwórz plik z konfiguracją”
przekierowuje nas do linku http://twoja-domena.pl/wp-admin/setup-config.php
Link po instalacji jest dalej osiągalny po instalacji i nie wiem czy trzeba go usuwać po instalacji?
Ew. zmienić mu nazwę na np. ‚setup-config.php_’ ?

2. Pod tym właśnie adresem pojawia się komunikat „The file ‚wp-config.php’ already exists. If you need to reset any of the configuration items in this file, please delete it first. You may try installing now.”
Z kolei odkrywający kolejny link http://twoja-domena.pl/p-admin/install.php i nie wiem czy mam go też ukryć w jakiś sposób?

3. Tak samo niepokoi mnie plik wp-config-sample.php, który po instalacji nadal jest osiągalny!
„Jeśli automatyczne tworzenie pliku się nie powiedzie, należy otworzyć plik wp-config-sample.php edytorem tekstu, wstawić do niego informacje o bazie danych i zapisać jako wp-config.php.”

4. Szukam wtyczki do zmiany linku do logowania. Ponieważ standardowo do logowania sie do Panelu Administratora w każdym WordPressie stosowany jest link w postaci „http://twoja-domena.pl/wp-login.php”. Chce mieć dzięki tej wtyczce możliwość zmiany tego adresu na np. „http://twoja-stona.pl/bezpieczne-logowanie.php”

O czym należny zawsze pamiętać?

1. Zawsze aktualizuj WordPressa do najnowszej dostępnej wersji

2. Pobieraj szablony i wtyczki z zaufanych źródeł (a nie z wątpliwych lokalizacji)

3. Aktualne wersje wtyczek + można też przyjąć zasadę im jest ich mniej zainstalowanych tym lepiej

4. Regularny backup plików i bazy danych

Należy tworzyć regularny backup. Jest tyle sposobów, że hoho… ale nie będę ich opisywał tylko wymienię kilka o których można pamiętać:

Czytając ‚wytyczne’ można dodatkowo mieć na względzie:

  • kontrolę MD5 bazy aby zawsze mieć pewność, że plik jest oryginalny w 100%, można dodatkowo szyfrować archiwum kopii na hasło, wysyłać pliki na swoją pocztę e-mail (a nie składować na serwerze bezpośrednio w jakimś katalogu), ‚modne’ też są konta w chmurze które są nie dość, że dobrze zabezpieczone to dają nam jeszcze jedno miejsce z którego możemy odzyskać bazę i pliki

5. Firewall – na stronie forum WordPress pojawił się też link do wtyczki firewall http://www.seoegghead.com/software/wordpress-firewall.seo

  • Nie testowałem jej jeszcze ani innej podobnej ale w sumie ‚jak to firewall’ – umożliwia nam ustawienie połączeń z których możliwe jest tylko logowanie. Więc kiedyś trzeba będzie przyjrzeć się temu i znaleźć szybkie i skuteczne rozwiązanie…
  • PS. a propo firewall-a to jeżeli ktoś korzysta z serwera, który oferuje panel Direct Admin to też jest tam możliwość ustawiania z jakiego adresu IP może odbywać się logowanie

6.  Total Commander + WordPress = Problem! Ostatnio cały czas słyszę, że używanie TC do wrzucania plików na serwer to złe rozwiązanie, ponieważ w łatwy sposób można z niego (a raczej z zapisanych plików konfiguracji TC wyciągnąć dane – bo przecież nie są szyfrowane!). I też uczulam na to – lepiej korzystać z np. z FilleZilli którą polecam

 7. Wybieraj sprawdzony hosting – lepiej wydać nawet te 100zł rocznie za dobry i sprawdzony serwer niż skosić się na darmowy lub np.  współdzielony serwer który ma swoją lokalizację np. w Niemczech – na nim mogą też znajdywać się inne strony i nie koniecznie są dobrej jakości. O innych plusach takich serwerów nie będę nawet pisał

8. Posługuje się mocnymi hasłami – o tym to nie muszę wspominać

9. Usuń konto Administratora – A) – Zaloguj się na domyślnie stworzone przez Ciebie konto administratora. B) Załóż inne konto użytkownika nadając mu prawa administratora. C) Zaloguj się na nowe konto D) Usuń stare konto administratora

10. Zmień swój ‚Nick name’ – do podpisywanie się np. w komentarzach na stronie, tak aby był on inny od nazwy użytkownika któryego używasz do logowania na konto administratora. Ja np. posługuję się ‚user’

11. Zmniejszenie limitu nieudanych logowań – wydaje się być dość rozsądnym rozwiązaniem. Jak macie dobrą i aktualną wtyczkę do polećcie ją

12. Ustaw uprawnia plików – chmody (pisałem wyżej o tym)

13. Ukryj nazwę i wersje WordPressa – aby nie „pokazywać wszystkim” na czym zrobiona postawiona jest nasza strona www. Można poszukać samemu jakiś wtyczek lub samemu ręcznie wykasować parę rzeczy w kodzie szablonu. Przykładowy kod do wklejenia w pliku functions.php swojego szablonu:
// remove version info from head and feeds
function complete_version_removal() {
return ”;
}
add_filter(‚the_generator’, ‚complete_version_removal’);

14. Wyłączenie rejestracji użytkowników – w Panelu Admina WordPressa (standardowe działanie)
15. Usunięcie zbędnych plików takich jak readme.html i innych
16. Dodatkowe możliwości:
– łączenie tylko z danego IP (konfiguracja najlepiej na serwerze – hostingu)
– wymuszenie logowania przez SSL (jeśli posiadasz certyfikat SSL)
// this goes in your wp-config.php file
//
//for just the login
define(‚FORCE_SSL_LOGIN’, true);
//for the whole admin
define(‚FORCE_SSL_ADMIN’, true);

17. Zablokowanie dostępu robotom do katalogów – aby nie indexowały a tym samym przez pomyłkę ktoś nie mógł wykorzystać cennych informacji
Przykładowa zawartość robots.txt w katalogu głównym:
User-agent: *

Disallow: /feed/
Disallow: /trackback/
Disallow: /wp-admin/
Disallow: /wp-content/
Disallow: /wp-includes/
Disallow: /xmlrpc.php
Disallow: /wp-

18. Zabezpieczenie pliku .htacces – parę reguł które ‚trochę’ podniosą bezpieczeństwo strony
//limit indexing of directories
Options All -Indexes

//protect the htaccess file,
//this is done by default with apache config file,
// but you never know.
<files .htaccess>
order allow,deny
deny from all
</files>

//disable the server signature
ServerSignature Off

//limit file uploads to 10mb
LimitRequestBody 10240000

// protect wpconfig.php.
//If you followed step 6 this is not necessary.
<files wp-config.php>
order allow,deny
deny from all
</files>

 19. Dodatkowe sposoby na poprawienie bezpieczeństwa – jest ich jeszcze 19 punktów których nie będę opisywał tylko podam link http://wpsecure.net/secure-wordpress-advanced/