Napadený WordPress neopravujte tak, že smažete první podezřelý soubor. Cílem je zastavit škody, zachovat důkazy, najít vstupní bod a vrátit web do provozu bez backdooru. Níže je postup, který používáme u webů i WooCommerce e-shopů.
Nejdřív zastavte škody, potom čistěte soubory
První chyba je pracovat na živém webu, který dál obsluhuje návštěvníky. Pokud web přesměrovává na cizí domény, rozesílá spam nebo hostuje phishing, přepněte ho na HTTP 503. Nevracejte 200 s hláškou o údržbě, vyhledávačům tím říkáte něco jiného.
Izolace nemusí znamenat vypnutí celého serveru. Stačí blokovat veřejný provoz, nechat přístup přes VPN nebo IP whitelist a zachovat databázi i logy. Pokud máte reverzní proxy nebo DNS správu oddělenou od hostingu, použijte ji pro rychlé přesměrování provozu na statickou stavovou stránku.
Nastavte webu návratový kód 503 a krátké hlášení bez detailů o incidentu.
Zablokujte administraci pro všechny IP adresy kromě vybraných správců.
Pozastavte SMTP odesílání, pokud existuje podezření na spam.
Zakonzervujte access logy, error logy a auditní logy minimálně z posledních 7 dnů.
Nevyprazdňujte cache dřív, než víte, zda neobsahuje důkaz přesměrování nebo vložený skript.
U e-shopu přidejte kontrolu plateb a objednávek. Pokud útočník měnil checkout, kupony nebo e-maily, nestačí vyčistit šablonu. Musíte ověřit i stav objednávek, callbacky platebních bran a účty s rolí správce obchodu.
Záloha napadeného stavu je důkaz, ne návratový bod
Před čištěním udělejte 1 kompletní kopii souborů, databáze a konfigurace serveru. Je to důkazní snapshot, ne kandidát pro produkční obnovu. Bez něj si snadno smažete jedinou stopu k tomu, odkud kompromitace přišla.
Snapshot uložte mimo napadený hosting. Pokud je server kompromitovaný hlouběji než WordPress, lokální záloha ve stejném účtu může zmizet nebo se sama kontaminovat. Zálohu označte datem, časem, doménou a hashem archivu.
mkdir -p ~/incident-wordpress-$(date +%F)
cd /var/www/example.com
# soubory včetně skrytých položek a časů úprav
tar --xattrs --acls -czf ~/incident-wordpress-$(date +%F)/files.tar.gz .
# databáze; údaje berte z wp-config.php
mysqldump --single-transaction --routines --triggers \
-u DB_USER -p DB_NAME > ~/incident-wordpress-$(date +%F)/database.sql
sha256sum ~/incident-wordpress-$(date +%F)/* > ~/incident-wordpress-$(date +%F)/SHA256SUMS.txt
Pokud hosting nedovoluje shell, stáhněte archiv přes správce souborů a exportujte databázi přes phpMyAdmin. Není to ideální, ale pořád lepší než začít mazat bez kopie. U větších webů hlídejte, aby export nebyl zkrácený limitem PHP.
Jak poznat, odkud se útočník do WordPressu dostal
Vstupní bod bývá nudný: zastaralý plugin, nulled šablona, slabé heslo, ukradené FTP nebo nezabezpečený upload. Nehledejte jen malware, hledejte mechanismus návratu. Jinak web vyčistíte a za den řešíte stejný incident znovu.
Začněte časovou osou. Najděte první podezřelý požadavek, první změněný PHP soubor a první vytvořený účet. Časy v access logu, databázi a souborovém systému se nemusí dokonale shodovat, ale rozdíl v řádu minut je použitelný.
POST požadavky na admin-ajax.php, xmlrpc.php nebo upload endpointy těsně před změnou souborů.
Nové PHP soubory v wp-content/uploads, kde běžně nemá být spustitelný kód.
Administrátor vytvořený mimo běžnou pracovní dobu nebo z neznámé IP adresy.
Změny v wp_options, hlavně siteurl, home, active_plugins a cron.
Neznámé úlohy ve WordPress cronu nebo systémovém cronu hostingu.
Logy porovnávejte i s veřejně známými slabinami. Pokud čas kompromitace sedí na vydaný exploit pluginu, máte silný signál. Neznamená to ale, že můžete ignorovat hesla; kombinované útoky přes leak účtu a zranitelný plugin jsou běžné.
Souborový systém: checksums, mtime a podezřelé PHP
Jádro WordPressu nikdy neopravujte ručním porovnáváním soubor po souboru. Použijte WP-CLI a ověřte checksumy proti oficiálním balíčkům. Příkaz wp core verify-checksums odhalí změny v jádře rychleji než grep.
cd /var/www/example.com
wp core version
wp core verify-checksums --locale=cs_CZ
# pokud web používá anglické jádro, locale parametr vynechte
wp plugin list --fields=name,status,version,update
wp theme list --fields=name,status,version,update
U pluginů je situace horší. WP-CLI umí přes wp plugin verify-checksums ověřit pluginy z wordpress.org, ale placené pluginy a vlastní kód tím nepokryjete. Ty instalujte znovu z důvěryhodného zdroje.
# PHP soubory v uploadech jsou silný signál kompromitace
find wp-content/uploads -type f -name '*.php' -print
# nedávno měněné PHP soubory v obsahu webu
find wp-content -type f -name '*.php' -mtime -14 -print
# typické maskování: dvojité přípony nebo náhodné názvy
find wp-content -type f \( -name '*.php.*' -o -name '*.phtml' -o -name '.*.php' \) -print
Podezřelý soubor neotevírejte přes webový prohlížeč. Čtěte ho lokálně v editoru nebo přes less. Typické backdoory používají eval, base64_decode, gzinflate, dynamické názvy funkcí a řetězce rozdělené na kusy.
Databáze: administrátoři, options a injektovaný obsah
Útočník nemusí měnit žádný soubor. Stačí mu administrátor, vložený JavaScript v obsahu nebo změna hodnoty v wp_options. Proto databázi kontrolujte stejně pečlivě jako souborový systém, hlavně u webů s editorem obsahu pro více lidí.
Začněte účty. Vypište všechny administrátory a porovnejte je s reálným seznamem lidí. Kontrola musí pokrýt 100 % účtů s vysokými právy, včetně starých agenturních přístupů, testovacích uživatelů a účtů dodavatelů.
# administrátoři přes WP-CLI
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
# podezřelé options
wp option get siteurl
wp option get home
wp option get active_plugins --format=json
wp option get cron --format=json | head -c 2000
# hledání skriptů v obsahu příspěvků
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%' OR post_content LIKE '%iframe%';"
U databázových prefixů nepočítejte automaticky s wp_. Skutečný prefix najdete ve wp-config.php. Pokud má web více instalací v jedné databázi, zkontrolujte všechny tabulky; malware často sedí v zapomenuté kopii webu vedle produkce.
wp_users a wp_usermeta: role, e-maily, datum registrace a neznámé účty.
wp_options: přesměrování, aktivní pluginy, cron a autoloadované hodnoty.
wp_posts: vložené skripty, iframe, skryté odkazy a přepsané šablonové bloky.
wp_terms a wp_termmeta: spamové kategorie a SEO odkazy.
Vlastní tabulky pluginů: formuláře, objednávky, feedy a napojení na externí API.
Volba opravy: obnova ze zálohy, ruční čištění, rebuild
Existují 3 reálné strategie. Obnova ze zálohy je rychlá, ale bezpečná jen při známém datu napadení. Ruční čištění je vhodné pro menší zásahy. U vážnějšího incidentu doporučujeme čistý rebuild a přenos pouze ověřených dat.
| Strategie | Kdy dává smysl | Hlavní riziko |
|---|---|---|
| Obnova ze zálohy | Znáte čisté datum zálohy a vstupní bod incidentu | Vrátíte i zranitelný plugin nebo ukradený přístup |
| Ruční čištění | Malware je lokální a web je malý | Přehlédnete backdoor v databázi nebo mu-pluginu |
| Čistý rebuild | Neznáte rozsah kompromitace nebo jde o e-shop | Trvá déle a vyžaduje přesnou migraci obsahu |
| Forenzní analýza | Řeší se únik dat, škoda nebo právní dopad | Vyšší náklady a nutnost neměnit důkazy |
Pokud web obsahuje osobní údaje, objednávky nebo členské sekce, řešte i právní stránku incidentu. Technická oprava neodpoví sama o sobě na otázku, zda došlo k úniku dat. Pro e-shop je to rozdíl mezi běžnou údržbou a bezpečnostním incidentem.
Z praxe: když není jistota, volíme rebuild. Ruční čištění má smysl jen tam, kde rozumíte kódu, znáte historii změn a máte oddělený repozitář. Bez toho je to spíš lov náhodných symptomů než oprava příčiny.
Čistá instalace WordPressu bez přenesení backdooru
Čistý rebuild znamená nové soubory z oficiálních zdrojů, ne kopii starého public_html. Jádro WordPressu stáhněte z wordpress.org, pluginy z repozitáře nebo účtu dodavatele a vlastní šablonu z Gitu, ne z napadeného hostingu.
Z původního webu přenášejte jen data, která projdou kontrolou. Typicky databázový obsah, média bez spustitelných souborů a konfigurační hodnoty ověřené proti dokumentaci. Nepřenášejte mu-plugins, cache adresáře, staré zálohy ani neznámé drop-in soubory.
# příklad bezpečnějšího rebuild postupu
mkdir /var/www/example-clean
cd /var/www/example-clean
wp core download --locale=cs_CZ
wp config create --dbname=DB_NAME --dbuser=DB_USER --dbpass='DB_PASS' --dbhost=localhost
# instalujte pluginy znovu, nepřenášejte jejich staré adresáře
wp plugin install contact-form-7 --activate
wp plugin install wordpress-seo --activate
# média kopírujte selektivně a bez PHP
rsync -av --exclude='*.php' --exclude='*.phtml' /var/www/example-old/wp-content/uploads/ wp-content/uploads/
U šablon je nejlepší mít zdroj v repozitáři a produkci jen jako deploy artefakt. Pokud šablona existuje pouze na hostingu, berte ji jako podezřelou. Zkontrolujte minimálně functions.php, vlastní endpointy, AJAX akce a práci se vstupy.
Hesla, klíče, cookies a přístupy po incidentu
Po opravě souborů rotujte přístupy. Nestačí změnit heslo hlavního administrátora. Útočník mohl získat FTP, SSH, databázi, SMTP, hostingový panel, externí služby nebo aktivní cookie relace přihlášených správců.
WordPress používá 8 autentizačních klíčů a salt hodnot v wp-config.php. Jejich změna odhlásí existující relace. Udělejte ji po vyčištění a před návratem webu do veřejného provozu, jinak můžete útočníkovi nechat platnou session.
# vygeneruje nové klíče do wp-config.php
wp config shuffle-salts
# vynuťte reset hesel administrátorů podle interního procesu
wp user list --role=administrator --fields=ID,user_login,user_email
Administraci dejte za dvoufaktorové ověření. U klientských webů doporučujeme minimálně 2FA pro všechny administrátory a editory s právem měnit šablony, pluginy nebo uživatele. Jeden slabý účet stačí k návratu problému.
Hardening po opravě: práva, aktualizace a logování
Opravený web bez hardeningu je jen dočasně čistý. Oficiální dokumentace Hardening WordPress uvádí konkrétní oblasti: aktualizace, práva souborů, databázi, server, SSL a omezení přístupu.
Na sdíleném hostingu nemáte kontrolu nad vším, ale pořád umíte snížit riziko. Vypněte editaci souborů z administrace, zakažte PHP v uploadech, nastavte práva 755 pro adresáře a 644 pro běžné soubory.
# wp-config.php
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', false); // true jen pokud aktualizace řešíte deployem
# práva souborů z kořene webu
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod 640 wp-config.php
Do wp-content/uploads přidejte pravidlo, které nespustí PHP. Přesná syntaxe závisí na Apache, Nginx nebo hostingu. Princip je stejný: média mají být statická data, ne runtime prostor pro kód útočníka.
# Apache: wp-content/uploads/.htaccess
<FilesMatch "\.(php|phtml|phar)$">
Require all denied
</FilesMatch>
# Nginx: blok vložte do server konfigurace
location ~* /wp-content/uploads/.*\.(php|phtml|phar)$ {
deny all;
}
Nezapomeňte na HTTPS, automatické aktualizace bezpečnostních verzí a logování přihlášení. Pokud web jede za CDN nebo proxy, ukládejte skutečnou IP klienta korektně, jinak jsou access logy při dalším incidentu skoro nepoužitelné.
Ověření před návratem do veřejného provozu
Před přepnutím provozu proveďte technickou i aplikační kontrolu. Nestačí otevřít homepage. Ověřte přihlášení, formuláře, objednávkový proces, e-maily, sitemapu, robots.txt, canonical URL a odpovědi pro mobilní i desktopový user-agent.
Zkontrolujte i indexovatelné stránky. Hacked SEO spam se často projeví jen na náhodných URL, ve vyhledávání nebo při přístupu z konkrétního refereru. Pokud řešíte i výkon po opravě, navazuje na to článek proč je WordPress web pomalý.
# rychlá kontrola stavových kódů a přesměrování
curl -I https://example.com/
curl -I https://example.com/wp-login.php
curl -I -A "Googlebot" https://example.com/
# kontrola nečekaných PHP souborů po rebuild procesu
find wp-content/uploads -type f -name '*.php' -print
# kontrola čekajících aktualizací
wp core check-update
wp plugin list --update=available
wp theme list --update=available
Po návratu sledujte logy alespoň prvních 48 hodin aktivně. Hledejte opakované POST požadavky na stejný endpoint, neexistující soubory s příponou PHP, pokusy o xmlrpc a přihlášení na smazané účty. Tady se často ukáže, zda jste vektor opravdu uzavřeli.
Co si z opravy napadeného webu odnést
Oprava napadeného WordPressu je incident response, ne kosmetická údržba. Správné pořadí je izolace, záloha, analýza, rebuild, rotace přístupů, hardening a dohled. Když některý krok přeskočíte, zvyšujete šanci na opakovanou kompromitaci.
Největší technický dluh bývá v tom, že WordPress nemá repozitář, staging, pravidelné aktualizace ani plán obnovy. Incident je nepříjemný, ale zároveň jasně ukáže, kde systém potřebuje proces, ne jen další bezpečnostní plugin.
Pokud web vydělává peníze nebo pracuje s osobními údaji, doporučujeme řešit kompromitaci jako produkční havárii. Rychlá oprava má hodnotu jen tehdy, když po ní víte, co se stalo, co bylo zasaženo a proč se stejná cesta znovu neotevře.

Komentáře (0)
Přidat komentář
Váš email nebude zveřejněn. Všechny komentáře procházejí schválením administrátorem.