§

Vstup

Režim
Styl entity
Rozsah kódování
§

Výstup

Americké a britské webové týmy sahají po HTML entitním kódování pokaždé, když se uživatelem dodaný text ocitne uvnitř serverově renderované stránky nebo e-mailové šablony. OWASP XSS Prevention Cheat Sheet označuje entitní kódování jako Pravidlo #1 pro kontext HTML těla a NIST SP 800-53 kontroly SI-10 a SI-15 citují výstupní kódování jako základ pro federální webové aplikace. CMS pipeline zpravodajských redakcí u vydavatelů jako BBC prohánějí text entitními kodéry, než se dotkne veřejného webu, protože chytré uvozovky a em-pomlčky z novinářských konceptů by jinak rozbily feedové validátory. Tento kodér v prohlížeči používá asi 200 běžných pojmenovaných entit a číselný fallback pro zbytek, takže výsledek odpovídá tomu, co produkují `htmlspecialchars` nebo Reactův auto-escape v produkci.

Jak funguje HTML entitní kódování

HTML entita je znaková reference, kterou prohlížeč parsuje zpět na jeden znak. Pět vyhrazených HTML znaků (<, >, &, ", ') vždy vyžaduje kódování, když je text vykreslován jako HTML; vše ostatní je volitelné a závisí na kódování dokumentu.

  1. Výběr režimu a rozsahu. Režim Kódovat prochází váš vstup znak po znaku. Režim Dekódovat prochází vstup a hledá vzory entit. Přepínač rozsahu rozhoduje, zda se kóduje pouze pět HTML-safe znaků, nebo také každý ne-ASCII kódový bod.
  2. Výběr stylu entity. Pojmenované entity (&copy;) se dobře čtou ve zdroji. Desítkové reference (&#169;) a hex reference (&#xA9;) nesou každý Unicode kódový bod bez potřeby názvu. Starší e-mailoví klienti a XML parsery preferují číselné formy.
  3. Průchod vstupem. Při kódování čteme každý kódový bod a vyhledáme jej proti vestavěné tabulce asi 200 běžných pojmenovaných entit. Neúspěšné spadnou na číselné. Při dekódování prohledáváme jedním regexem, který odpovídá &name;, &#NNN; a &#xHH; v jednom průchodu.
  4. Mapování na znaky. Pojmenované shody se řeší přes reverzní tabulku. Číselné shody procházejí String.fromCodePoint se základem 10 nebo 16. Neznámé pojmenované entity jsou ponechány nedotčeny, takže částečný vstup prochází obousměrně beze ztrát.
  5. Živý režim. Přepněte živý režim a každý stisk klávesy znovu spustí konverzi se 150 ms debounce. Užitečné, když ladíte úryvek a chcete okamžitou zpětnou vazbu před vložením do šablony.

Proč kódovat HTML entity

  • Zabránění rozbití rozvržení uživatelským vstupem. Když uživatel napíše zbloudilý < do komentáře, vložení tohoto textu přímo do HTML přepíše zbytek stránky. Zakódování vyhrazených znaků nejprve znamená, že prohlížeč vykreslí znak místo parsování jako začátek tagu.
  • Udržení platných hodnot atributů. Vložení uvozovkovaného řetězce uvnitř HTML atributu vyžaduje nahrazení vložené uvozovky pomocí &quot; (pro atributy v dvojitých uvozovkách) nebo &#39; (pro atributy v jednoduchých uvozovkách). Jinak parser uzavře atribut brzy a zbytek řádku se stane zbloudilým markupem.
  • Zneškodnění náhodného HTML v uložených datech. Logy, hlášení chyb a exporty chatů často obsahují skutečné lomené závorky a ampersandy. Entitní kódování dumpu před vložením do dokumentační stránky udržuje tuto kopii viditelnou jako text místo spouštění rendereru nebo auto-detektoru odkazů.
  • Bezpečné sdílení úryvků kódu. Zveřejnění příkladu tagu jako <script>alert(1)</script> v blogovém příspěvku, e-mailu nebo Slack zprávě vyžaduje zakódování závorek, aby se úryvek zobrazil, nikoli spustil. Stejná technika pokrývá RSS feedy a JSON-LD `description` pole.

Běžné aplikace

Entitní kódování se objevuje všude, kde surový text je skládán do HTML za běhu — i když framework to obvykle zvládá za vás, manuální nástroj je užitečný pro momenty, kdy to nedělá.

  • Serverově renderované šablony: Jinja2, ERB, Twig a Handlebars auto-escapují ve výchozím nastavení, ale raw bloky a `safe` markery to vypínají — kodér vám umožní potvrdit, co by escape produkoval.
  • Tvorba e-mailů a newsletterů: mnoho ESP šablonovacích enginů neescapuje merge fieldy automaticky, takže chytré uvozovky a glyfy copyrightu v uživatelem dodaných jménech potřebují předkódování.
  • Dokumentace a ukázky kódu: vložení příkladu HTML tagu do Markdown blogového příspěvku nebo statického úryvku vyžaduje zakódování závorek, aby renderer zacházel s textem jako viditelným.

Příklad

Vložte <script>alert('hi')</script> do vstupu s režimem Kódovat, stylem Pojmenovaná, rozsahem Minimální. Výstup čte &lt;script&gt;alert(&#39;hi&#39;)&lt;/script&gt;. Přepněte styl na Číselná hex a stejný vstup vytvoří &#x3C;script&#x3E;alert(&#x27;hi&#x27;)&#x3C;/script&#x3E;. Přepněte režim na Dekódovat, vložte kódovaný řetězec zpět a původní tag se vrátí neporušený.

FAQ

Co jsou HTML entity?

HTML entity jsou znakové reference, které prohlížeč dosazuje zpět do jednotlivých znaků při parsování stránky. Přicházejí ve třech formách: pojmenované (jako &amp; pro &), desítkové číselné (&#38;) a hex číselné (&#x26;). Pět vyhrazených HTML znaků (<, >, &, ", ') potřebuje kódování pokaždé, když je text vložen do HTML. Zbývajících asi 2 225 pojmenovaných entit pokrývá symboly, akcenty a řecká písmena, ale jsou volitelné, jakmile je kódování dokumentu UTF-8.

Kdy mám použít pojmenované vs. číselné entity?

Použijte pojmenované entity, když chcete, aby zdroj byl čitelný (člověk revidující &copy; v šabloně to okamžitě pochopí). Použijte číselné (desítkové nebo hex), když je spotřebitel starší nebo přísnější — XML parsery, starší e-mailoví klienti a některé feedové čtečky rozpoznávají pouze malou podmnožinu HTML5 pojmenovaných entit a všechny rozpoznávají číselné formy. Hex vítězí v bezpečnostně zaměřených kontextech, protože se jedna ku jedné shoduje se zápisem kódového bodu Unicode používaným ve specifikačních dokumentech.

Zpracovává dekódování hex entity jako &?

Ano. Dekodér používá jediný regex, který odpovídá všem třem formám entity v jednom průchodu: &name;, &#NNN; a &#xHH;. Číselné shody jsou řešeny pomocí String.fromCodePoint se základem 10 nebo 16. Smíšený vstup (pojmenovaný a číselný v jednom řetězci) se dekóduje správně a neznámé názvy jsou ponechány jako doslovný text, takže částečný vstup prochází beze ztrát.

Je to bezpečné pro použití s nedůvěryhodným vstupem?

Samotný kodér je pouze v prohlížeči a neodesílá váš vstup nikam. Zda je výstup bezpečný k vložení, závisí na kontextu. Entitní kódování zpracovává kontexty HTML těla a hodnot atributů, což pokrývá případ OWASP Pravidla #1. JavaScriptové kontexty (inline event handlery, bloky <script>), CSS kontexty a URL kontexty každý vyžadují svá vlastní pravidla kódování — samotné entitní kódování zde nestačí. Pro serverovou obranu do hloubky spárujte toto s kontextově uvědomělým šablonovacím enginem jako DOMPurify nebo auto-escape vašeho frameworku.

Entitní kódování na straně prohlížeče sedí na hranici mezi uživatelským vstupem a vykresleným HTML. Provedení konverze lokálně znamená, že můžete zkontrolovat, co by váš framework vydal, bez odesílání původního textu nástroji třetí strany.