Aktuálna situácia: PHP2Shell. Dve kritické zraniteľnosti PHP (CVSS 9.2) umožňujú spustenie škodlivého kódu bez prihlásenia. Záplaty od 21. 10. 2026.Čo treba urobiť teraz →

Zabrániť XSS v PHP: bezpečne odraziť Cross-Site-Scripting

Ako vývojári zabránia Cross-Site-Scriptingu v aplikáciách PHP: kódovanie podľa kontextu, auto-escaping v šablónach, čistenie HTML a Content Security Policy.

Stav 5 min čítaniaPríručky

Stručne: XSS v PHP zabránite tak, že každý výstup kódujete podľa jeho kontextu: htmlspecialchars() pre HTML, json_encode() s ochrannými voľbami pre JavaScript, preverené URL pre odkazy. Šablóny s automatickým escapingom vám z toho veľa odoberú. Content Security Policy a cookies HttpOnly obmedzujú škodu, ak nejaká zraniteľnosť predsa zostane.

Prečo by sa mal Cross-Site-Scripting teraz skontrolovať tiež

Pozornosť je v októbri 2026 upriamená na PHP2Shell, dve kritické zraniteľnosti v interpreteri PHP, pre ktoré existujú záplaty od 21. 10. 2026. Mnohé podniky si v tejto súvislosti nechávajú preveriť svoje webové aplikácie. To je dobrá príležitosť pozrieť sa aj na slabiny vo vlastnom kóde, ktoré žiadna aktualizácia PHP neodstráni.

Cross-Site-Scripting, skrátene XSS, je jednou z nich. OWASP Top 10 vedie XSS v rámci kategórie Injection. Na rozdiel od zraniteľnosti na serveri smeruje útok tu proti návštevníkom a používateľom vášho webu, napríklad proti zákazníkom v e-shope alebo zamestnancom v backende.

Následky môžu byť značné: prevzaté relácie administrátorov, zmanipulované formuláre, ktoré posielajú údaje tretím stranám, alebo sfalšovaný obsah na vašom webe. Ak sa prevezme administrátorský účet, môže to viesť až k úplnej kontrole nad aplikáciou.

Ako vzniká XSS v aplikáciách PHP?

XSS vzniká, keď aplikácia vypisuje údaje z nedôveryhodného zdroja na stránku bez kontroly. Prehliadač potom nevie rozlíšiť medzi vaším obsahom a zavlečeným kódom a vykoná oboje.

Rozlišujú sa tri formy. Pri reflektovanom XSS pochádza obsah priamo z aktuálnej požiadavky, napríklad z hľadaného výrazu v URL. Pri uloženom XSS leží v databáze, napríklad v komentári alebo poli profilu, a zasiahne každého, kto stránku otvorí. XSS založené na DOM vzniká v JavaScripte prehliadača, keď skripty zapisujú hodnoty z URL do stránky.

Nedôveryhodné sú všetky údaje, ktoré nie sú pevne v kóde: polia formulárov, parametre URL, cookies, názvy súborov, odpovede externých rozhraní a obsah z vlastnej databázy, ktorý niekedy prišiel zvonku.

Správne kódovať výstup podľa kontextu

Najdôležitejšie pravidlo znie: kódovať pri výstupe, a to podľa miesta, kde hodnota pristane. Pre obsah HTML a atribúty v úvodzovkách je prostriedkom voľby htmlspecialchars(). Malá pomocná funkcia bráni zabudnutiu volieb:

<?php
function e(?string $wert): string
{
    return htmlspecialchars($wert ?? '', ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
}
?>
<h2><?= e($produkt['name']) ?></h2>
<input type="text" name="suche" value="<?= e($_GET['q'] ?? '') ?>">

Iné kontexty vyžadujú iné prostriedky:

Kontext Bezpečná metóda
Obsah HTML, atribút v úvodzovkách htmlspecialchars() s ENT_QUOTES a UTF-8
Údaje pre JavaScript json_encode() s JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_HEX_QUOT
Parameter v URL rawurlencode() pre jednotlivú hodnotu
Úplná URL zo vstupu používateľa Skontrolovať schému, povoliť len https a http, potom htmlspecialchars()
Atribúty bez úvodzoviek, obsluhy udalostí, CSS vyhnúť sa, hodnoty tam nevkladať

Pre údaje, ktoré potrebuje skript, je dátový atribút alebo blok JSON zvyčajne najčistejšou cestou:

<?php
$daten = json_encode($konfiguration, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
?>
<div id="app" data-konfig="<?= e($daten) ?>"></div>

V JavaScripte potom hodnotu načítate cez dátový atribút a obsah nastavujete pomocou textContent namiesto innerHTML.

Šablóny, čistenie HTML a frameworky

Šablónové nástroje ako Twig a Blade kódujú výstupy štandardne automaticky. To vylučuje veľkú časť typických chýb. Nebezpečné je to tam, kde sa toto správanie vedome vypína, napríklad filtrom raw v Twig alebo syntaxou {!! !!} v Blade. Také miesta by mali byť v kóde zriedkavé a pri každom review sa cielene kontrolovať.

Ak má vaša aplikácia vedome povoliť HTML od používateľov, napríklad formátovanie v komentároch alebo v redakčnom systéme, kódovanie nestačí, pretože HTML sa má zobraziť. Potom potrebujete preverenú knižnicu na čistenie, ako je HTML Purifier, ktorá prepustí iba pevný zoznam povolených prvkov a atribútov. Vlastné filtre s regulárnymi výrazmi sú podľa skúseností dierave.

Dôležité

Skontrolujte najmä oblasti backendu. XSS v zobrazeniach, ktoré vidia iba administrátori, sa často podceňuje, no zasahuje práve účty s najviac právami.

Nájsť XSS v existujúcom kóde PHP

V rozrastených aplikáciách nie je prvou otázkou zvyčajne to, ako správne kódovať, ale kde sa to doteraz zabudlo. Pragmatickým začiatkom je hľadanie miest, kde sa premenné vypisujú priamo:

# Priame výpisy údajov požiadavky
grep -rnE "(echo|print|<\?=)\s*\\\$_(GET|POST|REQUEST|COOKIE|SERVER)" src/ templates/ --include="*.php"
# Vypnutý auto-escaping v Twig a Blade
grep -rnE "\|raw|\{!!" templates/ resources/views/

Nálezy sú úlohy na preverenie, nie hotové zistenia. Uložené XSS takéto hľadanie nájde len čiastočne, pretože hodnoty tam pochádzajú z databázy. Preto navyše skontrolujte všetky zobrazenia, ktoré ukazujú obsah od používateľov: komentáre, profily, poznámky k objednávkam, tikety podpory. Pri CMS a e-shopoch k tomu výslovne patria pluginy a témy tretích strán, pretože tam sídli veľká časť logiky výstupu.

Druhá obranná línia: CSP a bezpečné cookies

Aj pri starostlivom kóde sa môže niektoré miesto prehliadnuť. Dve opatrenia potom obmedzujú škodu. Content Security Policy povolí prehliadaču iba skripty z určených zdrojov a zakáže vložené skripty, pokiaľ nie sú výslovne uvoľnené:

Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"

Takúto politiku zavádzajte postupne, najprv v čisto hlásnom režime cez Content-Security-Policy-Report-Only, pretože existujúce zapojenia analytických alebo platobných služieb sa zvyčajne musia doplniť. Ďalšie hlavičky popisuje príručka Bezpečnostné hlavičky pre weby.

Navyše by cookies relácie mali mať atribút HttpOnly, aby ich skripty nemohli vyčítať. Ako zabezpečiť session ako celok, je v príručke Zabezpečiť session v PHP. Príbuznú slabinu na strane databázy rieši príručka Zabrániť SQL injection v PHP.

Ako konkrétne pomáha PHP SOS?

  • Šablóny a výstupy vašej aplikácie kontrolujeme na chýbajúce alebo nesprávne kódovanie.
  • Nálezy posudzujeme podľa dosiahnuteľnosti a dotknutých účtov a ukazujeme konkrétne opravy.
  • Content Security Policy zavádzame postupne, bez rušenia funkcií e-shopu alebo platieb.
  • Po oprave znova testujeme a výsledok zdokumentujeme.

Nezávislú kontrolu popisuje služba Bezpečnostný audit a penetračný test.

Časté otázky

Stačí htmlspecialchars proti XSS?

Pre bežný text v obsahu HTML a v atribútoch v úvodzovkách áno, ak uvediete ENT_QUOTES a znakovú sadu UTF-8. V JavaScripte, v URL alebo v CSS platia iné pravidlá, tam je potrebné vlastné, vhodné kódovanie.

Mal by som vstupy filtrovať pri ukladaní alebo pri výstupe?

Kódujte pri výstupe, podľa cieľa. Vstupy by ste mali pri prijatí kontrolovať na prijateľnosť, napríklad dĺžku a formát. Kto filtruje iba pri ukladaní, prehliadne údaje z iných zdrojov a sťaží neskoršie použitie v iných kontextoch.

Čo prináša Content Security Policy?

Content Security Policy určuje, z ktorých zdrojov smie prehliadač načítavať a vykonávať skripty. Môže výrazne obmedziť dosah prehliadnutej zraniteľnosti XSS, ale nenahrádza správne kódovanie.

Ako povolím formátovanie ako tučné písmo alebo odkazy v komentároch?

Použite preverenú knižnicu na čistenie HTML s whitelistom povolených prvkov a atribútov. Vlastné regulárne výrazy na odstraňovanie skriptov sú náchylné na chyby a nemali by sa používať.

Zdroje

Okamžitý kontakt

Každá hodina sa počíta. Napíšte nám hneď.

Stručne opíšte systém, verziu PHP a svoje pozorovanie. Ozveme sa, vyjasníme situáciu a budeme pracovať na diaľku, kým nebude incident uzavretý a zdokumentovaný.

Okamžitá pomoc