WordPress – és ami mögötte van

Facebooktwittergoogle_pluslinkedin

"Minden rendszer biztonsága egészen a használhatatlanságig fokozható"

A fenti mottó természetesen esetünkben is igaz, így tökéletesen biztonságos rendszer a gyakorlatban nem létezik. Éppen ezért, egy rendszer biztonságosabbá tételekor a feladat mindig az, hogy megtaláljuk a megfelelő egyensúlyt a kényelem, használhatóság, üzemeltethetőség, ráfordítandó (anyagi és emberi) erőforrások és a biztonság között. Ez nem egyszerű feladat, és a végeredmény minden projektnél más és más lesz. Tehát, nincs olyan megoldás ami mindenki számára megfelelő és megvalósítható! Éppen ezért jelen cikkben igyekszem végignézni az összes olyan lehetőséget amivel egy webes alkalmazás - esetünkben a WordPress - biztonsága növelhető. Ebből aztán mindenki a neki megfelelő megoldásokat alkalmazhatja  lehetőségei, és rendelkezésre álló erőforrásai függvényében...

"Minden rendszer csak annyira biztonságos, mint a benne szereplő leggyengébb láncszem!"

A  fenti mondatot mindenképp érdemes már a tervezés során is figyelembe venni, hiszen egy ilyen látszólag egyszerű alkalmazás esetében is, a teljes rendszer valójában nagyon sok összetevőből áll. Ha ezek közül bármelyiket is figyelmen kívül hagyjuk, azzal a többi 'láncszem' biztonságosabbá tételébe fektetett munkát - és ezen keresztül az egész projekt sikerét kockáztatjuk.

A továbbiakban igyekszem sorban végigvenni az érintett elemeket, hogy mit lehet tenni a rendszer biztonságosabbá tételéért:

Kliens

A klines oldal - vagyis a saját számítógépünk (vagy gépeink) - ahonnan a rendszert adminisztrátori szinten elérjük, és kezeljük. Fura lehet, hogy pont ezzel kezdem, de általában erről feledkeznek meg legtöbben. Hiszen, ha már a kliens oldal kompromittálódott, akkor a többi egészen egyszerűen lényegtelen, mert az esetleges támadónak azokban nem kell hibákat vagy egyéb 'bejutási lehetőségeket' keresni, ugyanis egyből adminisztrátori hozzáférése van minden komponenshez a saját gépünkön keresztül... Hogy mit tehetünk a kliens oldal biztonságosabbá tétele érdekében? Éppen erről szól egy másik cikksorozatom: Biztonságos desktop OS?

TCP/IP

Ha egy látogató böngészi oldalainkat - akár jó, akár támadó szándékkal - akkor ez az a protokoll amit mindenképp használ - hiszen enélkül internet sem lenne. Így logikusnak tűnt, hogy ezzel kezdjem... Azonban, ez olyan téma, amihez komoly előtanulmányok szükségesek, és bőven túlmutatnak ezen cikk tartalmi lehetőségein, így csak néhány lehetőség amivel TCP/IP alapú támadások ellen védhetjük rendszerünket:

Hálózat

Leendő szerverünket különböző típusú hálózatokba helyezhetjük el:
  • web tárhely bérlés

Költséghatékonysága miatt a ez a leggyakoribb megoldás, ilyenkor viszont a tárgyalt rendszerelemek közül csak néhányra van egyáltalán rálátásunk (a hálózati környezet biztosan nincs köztük), és csak nagyon kevés esetben tehetünk mi magunk bármit is a biztonság érdekében. Így ilyenkor a webtárhely szolgáltatójára kell hogy bízzuk magunkat....

  • szerver hosting (co-location, szerver bérlés, virtuális szerver)

Egyel drágább, de még mindig megfizethető, így szintén gyakori megoldás. Ez esetben a hálózati környezet még mindig - a szolgáltató által biztosított - adottság számunkra, azonban a rendszer többi alkotóelemét mi birtokolhatjuk - így biztonságosabbá is tehetjük.

  • egyéb (saját) szerver terem

Ez a megoldás nyilván keveseknek adatik meg, persze - kompromisszumok árán ugyan - saját céges hálózatokban már a hálózat is lehet a fennhatóságunk alatt. Ez viszont szintén külön téma, amivel majd egy másik cikkben foglalkozunk részletesebben.

Protokoll

A fenti lehetőségeinktől függően, ha használhatunk valamilyen alkalmazás szintű tűzfal megoldást, akkor azon felül, hogy a HTTP protokoll sértésen alapuló támadások ellene is védve lesz szerverünk, tovább növelhetjük a rendszerünk biztonságát azzal, hogy URL szinten is korlátozhatjuk ki mihez férhet hozzá. Általánosan alkalmazható szabályokat itt sem lehet adni, de néhány szűrési lehetőség:
  • /wp-admin

Ezen könyvtár elérése csak azoknak szükséges, akiknek bejelentkezési, szerkesztői vagy teljes adminisztrátori jogai vannak. Ez egy céges oldal esetében biztosan konkretizálható, elérése így szűkíthető és akár külön authentikációhoz is köthető...

  • /wp-includes

Ezen könyvtár elérése egyetlen felhasználónak sem kell direktben, ezeket csak maga a program használja futás közben. Így publikus elérésük teljesen felesleges.

  • wp-config.php

Ez a WordPress konfigurációs állománya, melyben biztonsági szempontból érzékeny adatok is találhatók, publikus elérhetősége teljesen felesleges, és nagyon veszélyes is!

HTTP/HTTPS

Sok helyen említik hogy HTTPS protokoll használatával is növelhetjük weboldalaink biztonságát... Ha a /wp-admin könyvtárhoz való hozzáférés esetén valóban lehet értelme, azonban ennek megvalósításához több egyéb dolog is kellhet:
  • saját publikus IP
  • külön vhost a webszerveren
Az ehhez szükséges konkrét beállítások megtalálhatóak a WordPress hivatalos dokumentációjában is. Alkalmazás szintű tűzfal használata esetén, mindezt sokkal könnyebben és rengeteg egyéb lehetőség mellett a tűzfalon megoldhatjuk....

Operációs rendszer

Szintén olyan téma, ami szinte kifejthetetlen... Azonban egyáltalán nem elhanyagolható, hiszen ezen lakik az összes alkalmazás, ami a végleges rendszerünket alkotja, így az operációs rendszer megfelelő megválasztása, karbantartása és felügyelete sarkalatos kérdés.

Adatbázis

Esetünkben ez konkrétan MySQL adatbázis jelent, így ennek telepítése és beállítása kritikus a teljes WordPress rendszer biztonságára nézve. Alapvetően kétféle megközelítés létezik:
  • külön adatbázis szerver

Ennek akkor van igazán értelme, ha az a bizonyos külön adatbázis szerver nem csak a egyetlen WordPress telepítésnek szolgáltat adatbázisokat, hanem egyéb projektek számára is. Ez esetben lényeges, hogy a WordPress számára nyújtott egyetlen adatbázist - az adminisztrátoron kívül - csak egyetlen dedikált felhasználó érhesse el, akinek más adatbázisokhoz semmilyen hozzáférése nincs. Ez általában adott, hiszen a közös adatbázis szerver esetén a DBA-nak, és a kiszolgálón megtalálható többi adatbázis gazdájának is vitathatatlan érdeke. Ha több független WordPress szájtot hozunk létre, akkor is tartsuk be ezt az egyszerű szabályt, így ha egyiket 'megtörik', a többi még nem feltétlenül lesz érintett az eseményben...

Ez esetben fontos, hogy az adatbázis szerverhez csak az érintett  webszer(ek)től, és azoktól is csak a MySQL portján fogadjon kapcsolatokat. Ez a következő megoldásokkal biztosítható

- lokális csomagszűrő/tűzfal

- tűzfallal szeparált hálózat

Tovább növelhető az adatbázis és a web kiszolgáló közötti kapcsolat, ha a kapcsolatot SSL használatával titkosítjuk. Ezt a megoldást a MySQL támogatja, a WordPress hivatalosan nem, ami azt jelenti, hogy kis módosítást kell végeznünk a kódban:

--- wp-orig/wp-includes/wp-db.php    2011-06-27 22:47:04.000000000 +0200
+++ wp-SSL/wp-includes/wp-db.php    2011-11-03 14:05:55.707154724 +0100
@@ -1014,9 +1014,9 @@
      */
     function db_connect() {
         if ( WP_DEBUG ) {
-            $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true );
+            $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true, MYSQL_CLIENT_SSL);
         } else {
-            $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true );
+            $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true, MYSQL_CLIENT_SSL);
         }
 
         if ( !$this->dbh ) {

Ezek után,  az alkalmazás titkosított csatornán fog kommunikálni a MySQL szerverrel, ami lényegesen megnehezíti a forgalom lehallgatását, és a sikeres 'Man In The Middle' típusú támadásokat. Ezt természetesen SQL oldalról meg is követelhetjük:

GRANT all on .... IDENTIFIED by .... REQUIRE SSL;
  • adatbázis szerver és web szerver ugyan azon  'gépen'

Ez sokkal általánosabb eset, ám ez esetben a MySQL kiszolgálót úgy javasolt beállítani, hogy hálózaton egyáltalán ne legyen elérhető:

skip-networking

Természetesen, az "1 WordPpress telepítéshez 1 adatbázis, ahhoz és csak ahhoz hozzáférő egyetlen (SQL szintű) felhasználó szabály" itt is érvényes! Szerencsére, a telepítési dokumentációban is ezen szabály betartásával készültek a példák...

Ilyen esetben, a titkosításnak nem sok haszna van, hiszen az adatbázis és a webkiszolgáló közötti forgalom a gépen belül marad...

Web kiszolgáló

Tulajdonképpen, ez az alkalmazás ami futtatja a .php kódokat, kapcsolatot tart az adatbázissal és közvetve vagy közvetlenül a felhasználók böngészőjével: olvashatóvá teszi számukra az oldalainkat :)  Ebből következik, hogy ez biztosítja a legtöbb támadási felületet is. Természetesen, a lehetőségeink sokszor itt is korlátozottak lehetnek, a hálózatnál részletezett hosting megoldásoktól függően, ilyenkor megint csak a szolgáltatóban bízhatunk, hogy megfelelően konfigurált, és frissített web kiszolgálót biztosít számunkra... Az alább található példák Linux operációs rendszeren futó Apace kiszolgálót feltételeznek, de nagy részük független attól, hogy milyen operációs rendszeren milyen web kiszolgálót használunk:

Elérhetőség

Teljesen triviális igény, hogy a tárhelyre (vagy épp a saját szerverünkre) valahogy oda kell juttatni minimum a WordPress telepítéséhez szükséges állományokat.... Ez a művelet azonban különösen kritikus a rendszer egésze szempontjából, ugyanis ha valaki hozzáfér a feltöltési lehetőségeinkhez, az gyakorlatilag azt jelenti, hogy azt tesz az oldalainkkal, amit csak akar.
  • FTP

A leggyakoribb megoldás a különböző szerver hosting megoldások estében, azonban felhasználóként rálátásunk gyakorlatilag nincs, a szolgáltatóban kell bíznunk, hogy megfelelő biztonságos feltöltési lehetőséget nyújt a számunkra. Jó esetnek számít, ha FTPS elérési lehetőségünk is van. Ennek híján ugyanis a belépéshez szükséges account információk könnyedén mások birtokába kerülhetnek, sőt a feltöltött adataink - akár feltöltés közben is - egy esetleges gonosz támadó által módosíthatóak lehetnek.

  • SSH

Saját szerver alkalmazása esetén szinte egyértelmű, hogy ezt használjuk az állományok feljuttatására. Beállítási és biztonsági lehetőségei az egyszerű FTP-hez képest kimeríthetetlenek - annyira, hogy sajnos legtöbben nincsenek is tisztában mit lehet kezdeni valójában egy ssh eléréssel az adott szerveren!

Ha lehetőségünk van rá, kulcs alapú azonosítással javasolt használni, amivel tovább csökkenthetjük az illetéktelen hozzáférések lehetőségét.

Hosting szolgáltatók esetében azonban - a nem megfelelő hozzáértés és a rengeteg járulékos lehetőség miatt - sokszor többet árt mint használ ez a lehetőség...

Itt kell megemlítenem az olyan szoláltatókat akik előre telepített WordPress szájtokat biztosítanak az ügyfeleknek. Ilyen esetben ugyanis nincs szükség állomány feltöltési lehetőségre - ami biztonsági szempontból előny -  mert ami a webtartalomhoz kell,az az admin felületről feltölthető. Természetesen, ez esetben a szolgáltatónak kell(ene) gondoskodni az egész rendszer biztonságáról!

Állomány jogosultságok

Szinte minden hosting megoldás esetében lehetőségünk van az állományok jogait piszkálni. Egy alap telepítést feltételezve, én a következő scriptet használom:
# 01: chmod uog-rwx -R /var/www/zrubi.hu
# 02: chmod u+rwX -R /var/www/zrubi.hu
# 03: chmod g+rX -R /var/www/zrubi.hu
# 04: chmod g+w -R /var/www/zrubi.hu/wp-content/blogs.dir
# 05: chmod 400 /var/www/zrubi.hu/readme.html
# 06: chgrp www-data -R /var/www/zrubi.hu/
# 07: chown root -R /var/www/zrubi.hu/
Ahol a számozott sorok a következőt jelentik: Minden esetben a könyvtár a saját WordPress telepítési könyvtárát jelenti, és minden esetben rekurzívan végezzük a műveleteket...
  1. leszedünk minden jogot minden állományról és könyvtárról
  2. a saját felhasználónknak olvasási, és írási jogot adunk minden állományra és könyvtárra.
  3. a csoportnak olvasási jogot adunk minden állományra és könyvtárra.
  4. a csoportnak írási jogot adok a 'blogs.dir' könyvtárra
  5. a readme.html jogait beállítom úgy hogy azt a web kiszolgáló ne tudja megjeleníteni
  6. minden állomány a 'www-data' csoportnak birtokába adok
  7. minden állományt a root felhasználó birtokába adok
A fenti script csak abban az esetben működik, ha root jogosultságunk van a szerveren - ami csak saját szerver esetén normális ;) Egyéb esetekbe a következő a lényeg:
  • minden állomány a saját felhasználónk tulajdona legyen
  • minden állomány csoportja a web kiszolgáló csoportja legyen

Sok hosting szoláltatónál ez nem lehetséges, ilyenkor mindenki számára elérhetővé kell tennünk az állományokat, ami nagy kockázat, hiszen az adott gépen a 'szomszédunk' (hibás konfiguráció, vagy operációs rendszer szintű hibák esetén) beleláthat az állományokba, aminek során olyan információkhoz juthat (pl.: adatbázis hozzáférés) amit nem szerettünk volna vele megosztani...

  • Írási jogot csak magunknak adjunk, a 'többieknek' szükség szerint csak olvasást/hozzáférést

Van egy csomó olyan beépített funkció és plugin, ami írni is szeretne bizonyos állományokat, könyvtárakat. Ezek alapvető kockázatot jelentenek, hiszen így egy a kódban lévő - sikeresen kihasznált - hiba esetén a támadó is tud állományokat feltölteni vagy módosítani a saját érdekeinek megfelelően, ami aligha fog nekünk tetszeni.

Ilyen beépített funkció a frissítés is, ami viszont nagyon kényelmes dolog ;)

  • Írási jog a csoportnak (vagy mindenkinek) normál esetben csak a '/wp-contetnt/blogs.dir' könyvtárra szükséges

ez elkerülhetetlen, ide kerülnek ugyanis a szerkesztők által feltöltött, az oldalakon megjelenő anyagok (legfőképpen: képek, csatolmányok)

PHP

Kényes téma... ugyanis a php programnyelven nagyon könnyű programozni, aminek meglett az a hátulütője is, hogy mindenki hirtelen programozónak hiszi magát, és ennek következményeként biztonsági szempontból rengeteg minősíthetetlen program kerül napvilágra - illetve az internetre. Mint felhasználók, ez ellen szinte semmit sem tehetünk, ha tetszik egy program használjuk, ha nem akkor kidobjuk.... Mint üzemeltetők, a php megfelelő konfigurációjával, és biztonsági patchelésével kierőltethetünk bizonyos dolgokat, amik biztonságilag indokoltak lehetnek, ám a gyenge minőségű kódok ilyenkor szinte működésképtelenek - a végeredmény pedig az ügyfeleinknek/felhasználóinknak nem fog majd tetszeni. Itt is, mint az egész 'biztonságossabbá tétel' projekt folyamán a minden fél számára elfogadható egyensúlyra kell törekednünk. Hogy pontosan miket tehetünk a php programozási hibák kihasználásának megnehezítésében, az ismét hatalmas falat lenne, így most nem is próbálkozom ezzel. Néhány hasznos beállítási lehetőséget említenék csak, amit a php.ini-ből állíthatunk:
  • safe_mode
  • max_execution_time, max_input_time, memory_limit
  • error_reporting
  • display_errors
  • log_errors
  • register_globals
  • allow_url_fopen, allow_url_include
Bővebb infromációt a fenti beállításokról és azok megfelelő beállításairól a hivatalos dokumentáció ide vonatkozó részében található.

Egyéb biztonsági lehetőségek

Természetesen, az általunk használt webszerver is tartalmaz lehetőségeket a biztonság növelésére, ám ha ezt a szolgáltatótól kapjuk  akkor csak a '.htaccess' állományokkal variálhatunk:

.htaccess

Ez egy speciális állomány amiben a webszerver lehetősége közül szinte mindent használhatunk, anélkül, hogy magát a vhost konfigurációját kellene módosítanunk - amit egy átlagos hosting esetében nem is tehetnénk meg. /wp-admin könyvtár eléréséhez egy újabb authentikációs szintet vezethetünk be:
AuthUserFile    /etc/apache2/secrets.pwd
AuthType    Basic
AuthName    "WP Admin"
Require     valid-user
Satisfy     any

Order       Deny,Allow
Deny from   all
Ha ezt elhelyezzük a '/wp-admin/.hrtaccess állományba', ezzel megakadályozhatjuk, hogy bárki illetéktelen megpróbáljon belépni, vagy az admin scriptekben hibát keressen. Természetesen ez a legegyszerűbb példa, ennél komolyabbat - akár tanúsítvány alapú authentikációt is alkalmazhatnk. Cserébe egyel több jelszó amire figyelni kell... /wp-includes
# Block the include-only files.
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]
Ezt a DocumentRoot alá helyezve elérhetjük, hogy a nem publikus scripteket ne lehessen elérni. További lehetőség, hogy a könyvtár indexelést is kikapcsoljuk:
Options All -Indexes
Így biztosak lehetünk benne, hogy a nem publikus scriptekhez ne férhessen hozzá senki. További lehetőségekért, olvassuk el az alkalmazott webszerver dokumentációjának erre vonatkozó részeit.

DocumentRoot

Egy kevésbé ismert lehetőség, hogy a 'wp-config.php' konfigurációs állományt kitehetjük a DocumentRoot alól! Ez azt jelenti, hogy a webszerver ha akarja sem tudja megmutatni a tartalmát, amivel biztosíthatjuk, hogy véletlenül sem kerü senki elé a tartalma. Ez - a nem publikus odalak egy könyvtárral feljebb pakolása webes alkalmazások biztonságosabbá tételekor alapvető dolog. A DocumentRoot alá CSAK publikus dolgokat kellene pakolni... Nem is értem, hogy miért nem oda teszik az összes nem publikus scriptet... Akkor nem kellene külön kitalálni hogy mégse mutassa meg a webszerver ezt - meg azt az állományt.

Logolás

Ez megint olyan dolog, ami csak ritkán van saját kézben, ám egy esetleges betörés vagy egyéb hiba esetén nagyon hasznos lehet - tehát, érdekes lehet hogy miképp logol a szolgáltató, és rendelkezésünkre bocsátja-e valamilyen formában, ha szükségünk lenne rá...

Folyamatos felügyelet

Ismét szolgáltató függő, vagy ha saját szervert üzemeltetünk elengedhetetlen a folyamatos felügyelet - hogy ha valami probléma keletkezik a rendszerünkben minél hamarabb tudomást szerezzünk róla, ne csak akkor ha már nem elérhető az oldalunk...

Hardening

Saját szerver esetén még tovább mehetünk, és tovább tuningolhatjuk szervereinket a maximális biztonság érdekében. A téma szintén nem ide való, ám az ilyen módon speciálisan felkészített szerverek rengeteget jelenthetnek egy webes alkalmazás biztonsága szempontjából.

WordPress

Végül, de nem utolsó sorban ezen alkotóelemek védelmének megerősítése után érdemes magának az alkalmazásnak a megerősítésre koncentrálni: "WordPress - biztonságosan"

Összegzés

Ismételten javaslom, hogy ha biztonságosabb weboldalakat szeretnénk létrehozni WordPress segítségével, ne csak a jéghegy csúcsát nézzük! Már tervezéskor vegyük figyelembe a szolgáltatók által nyújtott lehetőségeket, így biztosan a sikerül megtalálni a számunkra legjobban megfelelő megoldást. Ha pedig inkább mégis szakértőkre bíznák weboldalaik biztonságos kialakítását, elhelyezését, vagy védelmét: lépjenek kapcsolatba velünk, szinte minden igényre tudunk megfelelő megoldást nyújtani.
Facebooktwittergoogle_pluslinkedin