Zabezpečení webu: oprávnění, hlavičky a bezpečnostní pluginy
Modul 7: Zabezpečení · Doba čtení: 10 minut
Cíl lekce: Po této lekci dokážete zabezpečit WordPress web pomocí oprávnění, nastavení a bezpečnostních hlaviček a dokážete posoudit přínos bezpečnostních pluginů.
Klíčové pojmy: zabezpečení (hardening), oprávnění k souborům (644, 755), DISALLOW_FILE_EDIT, žádné PHP ve složce uploads, výpis obsahu složky, skrytí verze, X-Powered-By, bezpečnostní hlavičky, zálohové soubory a .git ve webovém adresáři, WAF na serveru, WAF v pluginu, malware scanner
Co znamená zabezpečení (hardening)
Zabezpečení (hardening) znamená: nastavit web tak, aby chyba nebo únik způsobily co nejmenší škodu. Nenahrazuje aktualizace a silná hesla (lekce 7.2 a 7.3), ale zmenšuje následky. Představte si dům: aktualizace jsou zámky, zabezpečení znamená zajistit, aby se zloděj, který se přesto dostal dovnitř, nedostal k trezoru.
Oprávnění k souborům
Každý soubor a každá složka na serveru má oprávnění: kdo smí číst, zapisovat a spouštět. Zapisují se jako tři číslice, pro vlastníka, skupinu a ostatní. Doporučení z dokumentace WordPressu:
| Co | Oprávnění | Význam |
|---|---|---|
| Složky | 755 | Vlastník smí vše, ostatní mohou číst a otevírat |
| Soubory | 644 | Vlastník smí číst a zapisovat, ostatní pouze číst |
| wp-config.php | přísnější, například 600 nebo 640 | Číst smí pouze vlastník (a případně skupina webového serveru) |
Která hodnota pro wp-config.php funguje, závisí na tom, jak Váš hosting provozuje PHP: u většiny sdíleného hostingu běží PHP pod Vaším vlastním uživatelem, a pak stačí 600. Vyzkoušejte to a zkontrolujte, zda web stále funguje.
Nikdy 777. To znamená: kdokoli na serveru smí zapisovat. Návod, který říká „nastavte složku na 777, pokud nahrávání nefunguje“, řeší problém špatně. U kvalitního hostingu to navíc není nikdy potřeba.
Nastavení v wp-config.php
Pár řádků, které hodně pomohou (nad „to je vše, přestaňte upravovat“):
// Žádné úpravy souborů z administrace (Vzhled > Editor šablon a Pluginy > Editor pluginů).
define( 'DISALLOW_FILE_EDIT', true );
// Chybová hlášení nikdy nezobrazovat návštěvníkům (lekce 5.4).
define( 'WP_DEBUG', false );Pomocí DISALLOW_FILE_EDIT zmizí editor, kterým lze v administraci upravovat PHP soubory šablon a pluginů. Útočník, který ovládne účet administrátora, tak nemůže dvěma kliknutími vložit škodlivý kód do Vaší šablony. Pluginy stále můžete instalovat; chcete li zakázat i to (například u webu, který spravujete pro klienta), existuje DISALLOW_FILE_MODS, ale pak nebudou fungovat ani aktualizace z administrace.
Žádné PHP ve složce uploads, žádný výpis obsahu složky
Do wp-content/uploads patří obrázky a dokumenty, nikdy PHP soubory. Útočníci, kteří dokážou přes nějakou zranitelnost nahrát soubor, se právě snaží umístit tam PHP soubor a následně ho vyvolat. Zablokujte to pomocí .htaccess ve složce uploads (u LiteSpeed a Apache):
<Files *.php>
Require all denied
</Files>Vypněte také zobrazování výpisu složek. Bez souboru index.php nebo index.html ve složce některé webové servery zobrazí seznam všech souborů („Index of /wp-content/uploads/2026/11“). To je výloha pro každého, kdo hledá zálohy nebo citlivé dokumenty. V souboru .htaccess ve Vašem webovém adresáři:
Options -IndexesMnoho poskytovatelů hostingu to má již standardně vypnuté. Úkol v této lekci to ověří.
Žádné zbytky ve webovém adresáři
Vše ve webovém adresáři lze vyvolat přes web, kromě toho, co server spustí jako PHP nebo zablokuje. Nebezpečné jsou:
- kopie wp-config.php (
wp-config.php.bak,wp-config.old,wp-config.php~z textového editoru): obsahují heslo k databázi a jsou odeslány jako text (lekce 1.3); - zálohy jako
backup.zip,site.tar.gznebodatabase.sqlve webovém adresáři; - složka
.gitod vývojáře, pomocí které si může někdo stáhnout celý Váš kód (a někdy i hesla); - debug.log ve wp-content (lekce 5.4);
- staré instalační nebo testovací soubory, například
info.phpsphpinfo().
Zálohy ukládejte mimo webový adresář nebo mimo server a zbytky uklízejte.
Skrytí verze: malý přínos
WordPress standardně vkládá do HTML:
<meta name="generator" content="WordPress 7.1.4" />a totéž ve zdroji RSS. I PHP se někdy hlásí v hlavičce: X-Powered-By: PHP/8.3.14. Skrytí je rozumné, ale neočekávejte od něj příliš: útočné programy zranitelnost prostě zkusí bez ohledu na zobrazenou verzi a verzi lze často odvodit i z ?ver= za skripty. Skrytí je úklid, ne zabezpečení. Web, který skrývá svou verzi, ale neaktualizuje se, je stejně zranitelný.
Uděláte to takto, ve vlastním malém pluginu nebo v functions.php podřazené šablony (child theme):
remove_action( 'wp_head', 'wp_generator' );
add_filter( 'the_generator', '__return_empty_string' );A PHP hlavičku pomocí expose_php = Off v nastavení PHP u Vašeho poskytovatele hostingu (u DirectAdmin v Select PHP version, Options), nebo pomocí Header unset X-Powered-By v .htaccess.
Bezpečnostní hlavičky
Pomocí několika hlaviček řeknete prohlížeči, jak má s Vaším webem zacházet. Nejdůležitější:
| Hlavička | Co dělá |
|---|---|
Strict-Transport-Security | Pouze přes https (lekce 3.1) |
X-Content-Type-Options: nosniff | Prohlížeč nehádá, o jaký typ souboru jde; zabraňuje tomu, aby byl nahraný „obrázek“ spuštěn jako skript |
X-Frame-Options: SAMEORIGIN nebo Content-Security-Policy: frame-ancestors 'self' | Jiné weby nesmí Váš web zobrazit v rámci (frame); zabraňuje clickjackingu (neviditelné tlačítko Vašeho webu pod webem někoho jiného) |
Referrer-Policy: strict-origin-when-cross-origin | Při kliknutí na odkaz na jiný web se předá pouze Vaše doména, ne celá adresa |
Permissions-Policy | Vypne funkce prohlížeče, které Váš web nepoužívá (kamera, mikrofon, poloha) |
Content-Security-Policy | Přesně určuje, z jakých zdrojů smí pocházet skripty a styly. Účinné, ale u WordPressu a pluginů složité správně nastavit; začněte v režimu Report-Only |
V souboru .htaccess (u LiteSpeed a Apache):
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>Poté otestujte, zda vše funguje: vložený obsah, platební tlačítka, chatovací widget. Externí nástroje jako securityheaders.com a internet.nl ukážou, co Váš web skutečně odesílá.
Bezpečnostní pluginy, upřímně zhodnoceno
Existuje mnoho bezpečnostních pluginů (například Wordfence, Solid Security, All-In-One Security, Sucuri). Často v sobě sdružují: firewall, malware scanner, ochranu přihlašování, dvoufázové ověření, upozornění a seznam opatření pro zabezpečení. Užitečné, ale s omezeními:
- Firewall v pluginu (WAF) se spustí až ve chvíli, kdy běží PHP. Škodlivý požadavek musí nejdříve projít webovým serverem a PHP, než ho plugin vůbec zaznamená. Zranitelnost v PHP souboru, který je volán přímo, nebo útok, který silně zatíží samotné PHP, tak nemusí vždy zastavit. Firewall na serveru (například ModSecurity, Imunify360 nebo firewall Vašeho poskytovatele hostingu) je v řetězci dříve a zastaví více, aniž by výpočetní zátěž nesl Váš plugin. Zeptejte se svého poskytovatele hostingu, co běží na serveru.
- Scanner nalézá až dodatečně. Malware scanner Vám sdělí, že něco není v pořádku. To je cenné, ale nic to nezabrání. A scanner běžící na stejném serveru jako napadený web může být útočníkem upraven i on sám.
- Nenahrazují aktualizace. Plugin se známou zranitelností zůstává zranitelný, i když vedle něj běží bezpečnostní plugin. Některé bezpečnostní služby nabízejí „virtuální záplaty“, které zastaví známé útoky, dokud neprovedete aktualizaci; vhodné jako přemostění, ne jako náhrada.
- Jsou samy pluginem. Více kódu, více věcí k aktualizaci, občas i vlastní zranitelnost. A dva bezpečnostní pluginy současně se často vzájemně ruší.
- Stojí výpočetní výkon, zejména scannery běžící na Vašem vlastním serveru.
Rozumný postup: nejprve zjistěte, co už dělá Váš poskytovatel hostingu (firewall, kontrola malwaru, blokování pokusů o přihlášení). Doplňte to, co chybí, obvykle dvoufázové ověření a omezení počtu pokusů o přihlášení. Rozsáhlý bezpečnostní plugin je užitečný zejména u hostingu, který sám dělá málo.
Shrnutí
- Zabezpečení (hardening) omezuje škodu způsobenou chybou nebo zranitelností; nenahrazuje aktualizace a hesla.
- Složky 755, soubory 644, wp-config.php přísněji; nikdy 777.
- Zapněte DISALLOW_FILE_EDIT, zablokujte PHP ve složce uploads, vypněte výpis obsahu složek a odstraňte zálohy, .git a debug.log z webového adresáře.
- Skrytí verze je úklid, ne zabezpečení; bezpečnostní hlavičky pomáhají prohlížeči chránit Vaše návštěvníky.
- Firewall na serveru zastaví více než plugin; bezpečnostní pluginy jsou doplněk, ne náhrada.
Kvíz
Úkol
Úkol A7.4: Co Váš web ukazuje úplně všem? Zadejte adresu svého webu. Program načte domovskou stránku a RSS kanál (/feed/) a zkontroluje: neobsahuje li tag generator v HTML a ve feedu verzi WordPressu, nezobrazuje li hlavička X-Powered-By verzi PHP, a zda Váš web odesílá X-Content-Type-Options: nosniff, ochranu proti rámům (X-Frame-Options nebo frame-ancestors) a Referrer-Policy. Chybějící HSTS (lekce 3.1) a Permissions-Policy je v pořádku (oranžová).
Úkol A7.4b: Žádné zbytky ve webovém adresáři. Dokažte, že je to Váš vlastní web (TXT záznam nebo soubor s kódem úkolu). Program poté ověří krátký pevný seznam: složku /wp-content/uploads/ (žádný výpis obsahu), /.git/HEAD, /wp-content/debug.log a několik běžných názvů kopií wp-config.php. V pořádku je, pokud žádný z nich nevrátí obsah (404 nebo 403). Program nic jiného nezkouší a nic nemění.
Další čtení
Tyto články popisují jednotlivé kroky v panelech WebOké; v jiných panelech fungují obdobně.
- Příručka k DirectAdmin 11.5: Práva souborů a složek (chmod)
- Příručka k DirectAdmin 11.4: Zobrazení a úprava skrytých souborů jako .htaccess
- Příručka k DirectAdmin 15.10: Webový aplikační firewall
- Příručka k DirectAdmin 15.11: Imunify360: kontrola webu na malware
- Blokování souborů přes .htaccess, například plugin-googlemap2-proxy.php
- Zabezpečení PHP
- Zabezpečení WordPressu (developer.wordpress.org, anglicky): https://developer.wordpress.org/advanced-administration/security/hardening/
- Bezpečnostní hlavičky (MDN, anglicky): https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#security
