Slovník pojmů

XSS

XSS vzniká na výstupu, když se data zamění za kód. Základní obranou je kontextové escapování; CSP, sanitizace a bezpečné API pro DOM přidávají další vrstvy.

Stručná definice

Data musí zůstat daty i v okamžiku, kdy je čte prohlížeč.

Cross-site scripting umožní útočníkovi dostat do stránky kód, který se spustí se stejným originem jako napadená aplikace. Může číst data dostupná stránce, posílat požadavky jménem uživatele, měnit obsah administrace nebo přimět uživatele k další akci. Dopad závisí na tom, co aplikace zpřístupňuje v prohlížeči a jak chrání relaci.

Nejčastější příčina není „špatný JavaScript“, ale vložení hodnoty do nevhodného kontextu bez správného kódování. Kontextové escapování se řídí tím, zda jde o HTML, atribut, URL nebo JavaScript. Automatické escapování pokrývá běžný HTML výstup; raw HTML a ruční innerHTML musí být záměrné a pod kontrolou.

Kde ochranu používat

Každý výstup, který může obsahovat data mimo pevně napsanou šablonu

Nedůvěryhodná data nevznikají jen ve formuláři. Mohou pocházet z integrace, administrace nebo dříve uloženého záznamu.

  • název produktu, recenze, poznámka k objednávce a zpráva zákaznické podpory
  • data importovaná z marketplace, ERP, CSV či externího API
  • administrace, kde pracovník vidí obsah vložený jiným uživatelem
  • frontendový JavaScript, který skládá DOM z API dat nebo URL parametrů

Praktický příklad

Název produktu z externího katalogu

Importer načte název produktu z marketplace a uloží jej do databáze. V administraci se název vykreslí jako obyčejný text. I když jej poskytl dříve důvěryhodný partner, aplikace s ním pracuje jako s datem: mezi importem a zobrazením mohl být chybný mapping, kompromitovaný účet nebo jiný zdroj obsahu.

Ukázka je bezpečná pro textový obsah HTML elementu. Není univerzálním řešením pro atribut, URL, JavaScript nebo HTML editor. Pokud obchod potřebuje formátovaný popis, obsah se před uložením či zobrazením sanitizuje prověřeným allowlist sanitizérem; výsledek se pak rozlišuje od prostého textu.

<?php

// Bezpečné pro text uvnitř HTML elementu, například <h1>…</h1>.
$safeProductName = htmlspecialchars(
    $productName,
    ENT_QUOTES | ENT_SUBSTITUTE,
    'UTF-8',
);
?>
<h1><?= $safeProductName ?></h1>

Jak zranitelnost vzniká

Od nedůvěryhodného vstupu k interpretaci jako kódu

Bezpečný tok rozlišuje, odkud data přicházejí a v jakém přesném kontextu se později zobrazí.

  1. Data přijdou do systému Uživatel, administrátor, import či API dodá text, URL nebo strukturovaný obsah, který aplikace ještě nemá považovat za bezpečný.
  2. Data se uloží nebo předají Uložený obsah není automaticky bezpečný. Stored XSS může zasáhnout každého, kdo jej později otevře v administraci nebo na webu.
  3. Aplikace zvolí výstupní kontext Hodnota se má zobrazit jako text, atribut, URL, JavaScriptová data nebo povolené rich HTML; každý kontext má jiná pravidla.
  4. Výstup se správně ošetří Šablona použije automatické kontextové escapování, bezpečné DOM API nebo sanitizaci povoleného HTML. Nejde o slepé nahrazení několika znaků.
  5. Prohlížeč interpretuje stránku Správně kódovaná hodnota zůstane textem. CSP může omezit dopad zbytkové chyby, ale nemá být jedinou překážkou před spuštěním kódu.

Důležité pojmy

Správná ochrana závisí na tom, kde se hodnota objeví.

Jedno univerzální „escapování“ neexistuje. Bezpečné řešení začíná určením výstupního kontextu.

Reflected, stored a DOM XSS

Reflected XSS vrací vstup přímo v odpovědi, stored XSS se nejprve uloží a může zasáhnout více uživatelů. DOM XSS vzniká v klientském JavaScriptu při nebezpečné práci s daty a DOM.

Kontextové escapování

HTML text, atribut, URL a JavaScript mají jinou syntaxi. Výstup se kóduje až podle místa použití; dřívější obecné escapování při ukládání vede k chybám zobrazení i falešnému pocitu bezpečí.

Sanitizace rich HTML

Když popis opravdu potřebuje omezené HTML, sanitizér odstraní nepovolené elementy, atributy a URL schémata podle allowlistu. Regulární výraz ani ruční blacklist není spolehlivý bezpečnostní model.

Bezpečné DOM API

Pro text se v JavaScriptu používá textContent nebo podobné bezpečné API. innerHTML, insertAdjacentHTML a dynamické URL či event handlery jsou hranice, kde je nutné data validovat nebo sanitizovat podle kontextu.

CSP a HttpOnly

CSP omezuje spuštění či načtení obsahu a HttpOnly čtení cookie JavaScriptem. Nezabrání všem akcím spuštěného skriptu v uživatelově relaci.

Vztah k jiným ochranám

XSS není totéž co validace, CSRF ani SQL injection.

Tyto chyby mohou mít společný nedůvěryhodný vstup, ale odehrávají se na jiné hranici a potřebují jinou primární obranu.

Validace vstupu
Kontroluje businessový formát, například délku názvu nebo povolený stav objednávky. Sama nezná všechny budoucí výstupní kontexty a nenahrazuje escapování.
CSRF
Brání cizímu webu podvrhnout cookie request. XSS běží ve vlastním originu a může token ze stránky použít, proto je potřeba obojí.
CSP
Je defense in depth pro prohlížeč. Dobrá politika nespraví nebezpečný raw HTML výstup ani nevyčistí data uložená v databázi.
SQL injection
SQL injection mění databázový příkaz na serveru a brání se parametrizací. XSS mění interpretaci obsahu v prohlížeči a brání se kontextovým výstupem.

Výhody a omezení

Přísný výstupní model chrání uživatele, ale vyžaduje jasný účel obsahu.

Přínosy

  • automatické escapování v šablonách pokrývá velkou část běžného HTML výstupu
  • oddělení textu od rich HTML zjednodušuje review a audit obsahu
  • sanitizační allowlist dovolí omezené formátování bez povolení libovolného kódu
  • CSP a HttpOnly přidávají další vrstvu při chybě v aplikaci

Rizika a chyby

  • použít raw HTML nebo innerHTML pro data jen proto, že se „špatně formátují“
  • přenést HTML escaping do JavaScriptového či URL kontextu, kde neplatí stejná pravidla
  • věřit datům z vlastní administrace nebo externí integrace bez stejného výstupního modelu
  • spoléhat na CSP, HttpOnly nebo CSRF token místo opravy zdroje XSS

Kdy je nutná

Vždy, když stránka zobrazuje proměnlivý obsah.

Ochrana proti XSS je základ webové aplikace bez ohledu na to, zda data pocházejí od veřejného uživatele, obchodního partnera nebo interní obsluhy. E-shop zvlášť často přenáší dlouhé popisy, názvy produktů, poznámky, marketingový obsah a odpovědi z API mezi více systémy. Každá hranice může změnit, kdo obsah kontroluje.

Nejjednodušší bezpečný model je zobrazovat data jako text a rich HTML podporovat jen tam, kde je skutečně potřeba. Editor obsahu potřebuje oddělenou sanitizační politiku, testy povolených i zakázaných konstrukcí a aktualizovanou knihovnu. Čitelné omezení je bezpečnější než neurčitá svoboda formátování.

Na co myslet

Escapovat při výstupu a kontrolovat výjimky z automatické cesty.

Review by mělo rychle odhalit místa, kde se data mění na HTML, JavaScript, URL nebo dynamický DOM.

  • ponechat automatické escapování šablon zapnuté a raw výstup povolit jen s jasným důvodem
  • volit enkódování podle HTML, atributového, URL, JavaScriptového nebo CSS kontextu
  • pro textový DOM používat textContent místo innerHTML a podobných HTML sinků
  • sanitizovat povolené rich HTML prověřeným allowlist nástrojem a testovat jeho pravidla
  • nasadit CSP jako obranu do hloubky a sledovat její porušení bez přidávání širokých výjimek

Časté otázky

Jak o XSS rozhodovat v praxi

Stačí data validovat při uložení?

Ne. Validace řeší, zda data odpovídají businessovým pravidlům, ale stejná hodnota se může později objevit v HTML, URL nebo JavaScriptu. Ochrana XSS se provádí podle konkrétního výstupního kontextu.

Je HTML escaping stejné pro atribut a JavaScript?

Ne. Každý kontext má jinou syntaxi a jiná nebezpečná místa. Nejjistější je nepsat data do JavaScriptového kódu ani dynamického HTML, pokud lze použít strukturovaná data a bezpečné API.

Mohu pro editor popisů použít raw HTML?

Pouze pokud je obsah předem bezpečně sanitizovaný prověřeným allowlistem a tým ví, jaký kontrakt takový obsah má. Neescapovaný výstup z běžného textového pole není bezpečný.

Nahradí CSP ochranu proti XSS?

Ne. CSP zmenšuje dopad některých cest, ale specifikace i praxe ji berou jako defense in depth. Základem zůstává bezpečné vytváření HTML a JavaScriptu.

Ochrání HttpOnly cookie před dopadem XSS?

Omezuje přímé přečtení označené cookie skriptem, ale spuštěný kód může často stále provádět požadavky v uživatelově relaci nebo číst data dostupná stránce.

Jak pracuji s PHP v praxi

Bezpečný výstup patří ke každému backendovému a e-commerce toku.

U aplikací řeším práci s externími daty, šablonami, administrací i bezpečnostní hranicí mezi prohlížečem, API a databází.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.