§

Wejście

Tryb
Styl encji
Zakres kodowania
§

Wyjście

W polskim sektorze fintech i administracji publicznej poprawne kodowanie znaków wyjściowych to wymóg bezpieczeństwa, nie tylko dobra praktyka. Wytyczne KNF dotyczące bezpiecznego kodowania dla banków i instytucji płatniczych wskazują kodowanie encji HTML jako środek zapobiegający atakom XSS w aplikacjach klientów. NASK, prowadzący badania nad cyberbezpieczeństwem, podkreśla walidację i kodowanie wyjścia jako pierwszą linię obrony przed iniekcją kodu. Standardy KSC — Krajowe Standardy Cyberbezpieczeństwa — wymagają od operatorów usług kluczowych stosowania kodowania wyjściowego zgodnego z OWASP Top 10. Narzędzie działa wyłącznie w przeglądarce, więc wklejane dane wrażliwe nigdy nie opuszczają urządzenia.

Jak działa kodowanie encji HTML

Encja HTML to odwołanie do znaku, które przeglądarka parsuje z powrotem do pojedynczego znaku. Pięć zarezerwowanych znaków HTML (<, >, &, ", ') zawsze wymaga kodowania podczas renderowania tekstu jako HTML; pozostałe są opcjonalne i zależą od kodowania dokumentu.

  1. Wybierz tryb i zakres. Tryb kodowania przetwarza wejście znak po znaku. Tryb dekodowania skanuje wejście w poszukiwaniu wzorców encji. Przełącznik zakresu decyduje, czy kodowane są tylko pięć znaków zarezerwowanych HTML, czy też każdy punkt kodowy spoza ASCII.
  2. Wybierz styl encji. Encje nazwane (&copy;) są czytelne w kodzie źródłowym. Odwołania dziesiętne (&#169;) i szesnastkowe (&#xA9;) obejmują każdy punkt kodowy Unicode bez potrzeby nazwy. Starsze klienty pocztowe i parsery XML preferują formy numeryczne.
  3. Przetwarzanie wejścia. Podczas kodowania każdy punkt kodowy jest wyszukiwany w wbudowanej tabeli około 200 popularnych encji nazwanych. Nieznalezione znaki otrzymują formę numeryczną. Podczas dekodowania stosowane jest pojedyncze wyrażenie regularne dopasowujące &name;, &#NNN; oraz &#xHH; w jednym przebiegu.
  4. Mapowanie na znaki. Dopasowania nazwane są rozwiązywane przez tabelę odwrotną. Dopasowania numeryczne przechodzą przez String.fromCodePoint w podstawie 10 lub 16. Nieznane encje nazwane pozostają bez zmian, dzięki czemu częściowe wejście jest konwertowane bez strat.
  5. Tryb na żywo. Włącz tryb na żywo, a każde naciśnięcie klawisza uruchomi konwersję z opóźnieniem 150 ms. Przydatne przy poprawianiu fragmentu kodu i potrzebie natychmiastowego podglądu przed wklejeniem do szablonu.

Dlaczego kodować encje HTML

  • Ochrona układu strony przed danymi użytkownika. Gdy użytkownik wpisze znak < w polu komentarza, wstawienie tego tekstu bezpośrednio do HTML może przepisać resztę strony. Zakodowanie zarezerwowanych znaków sprawia, że przeglądarka wyświetla znak zamiast interpretować go jako początek tagu.
  • Poprawność wartości atrybutów. Osadzenie łańcucha w cudzysłowie wewnątrz atrybutu HTML wymaga zastąpienia wbudowanego cudzysłowu przez &quot; (dla atrybutów w podwójnych cudzysłowach) lub &#39; (dla pojedynczych). W przeciwnym razie parser przedwcześnie zamknie atrybut.
  • Neutralizacja HTML w przechowywanych danych. Logi, zgłoszenia błędów i eksporty czatów często zawierają rzeczywiste nawiasy ostrokątne i ampersandy. Zakodowanie zrzutu przed wklejeniem na stronę dokumentacji sprawia, że treść jest widoczna jako tekst, a nie wyzwala renderera.
  • Bezpieczne udostępnianie fragmentów kodu. Umieszczenie przykładowego tagu jak <script>alert(1)</script> w poście blogowym, e-mailu lub wiadomości wymaga zakodowania nawiasów, aby fragment był wyświetlany, a nie wykonywany. Dotyczy to również treści kanałów RSS i pól `description` w JSON-LD.

Typowe zastosowania

Kodowanie encji pojawia się wszędzie tam, gdzie surowy tekst jest składany do HTML w czasie działania — nawet gdy framework zazwyczaj robi to automatycznie, ręczne narzędzie jest przydatne w momentach, gdy tak nie jest.

  • Szablony renderowane po stronie serwera: Jinja2, ERB, Twig i Handlebars domyślnie automatycznie uciekają, ale bloki surowe i znaczniki `safe` to wyłączają — kodek pozwala sprawdzić, co dałoby ucieczka.
  • Tworzenie wiadomości e-mail i newsletterów: wiele silników szablonów ESP nie ucieka automatycznie pól scalania, więc polskie cudzysłowy i znaki copyright w danych użytkownika wymagają wstępnego kodowania.
  • Dokumentacja i próbki kodu: wklejenie przykładowego tagu HTML do posta Markdown lub fragmentu strony statycznej wymaga zakodowania nawiasów, aby renderer traktował go jako widoczny tekst.

Przykład krok po kroku

Wklej <script>alert('hi')</script> do pola wejściowego z trybem Koduj, stylem Nazwany, zakresem Minimalny. Wynik to &lt;script&gt;alert(&#39;hi&#39;)&lt;/script&gt;. Zmień styl na Numeryczny szesnastkowy, a to samo wejście da &#x3C;script&#x3E;alert(&#x27;hi&#x27;)&#x3C;/script&#x3E;. Przełącz tryb na Dekoduj, wklej zakodowany ciąg — oryginalny tag wróci nienaruszony.

FAQ

Czym są encje HTML?

Encje HTML to odwołania do znaków, które przeglądarka zamienia na pojedyncze znaki podczas parsowania strony. Występują w trzech formach: nazwanej (np. &amp; dla &), numerycznej dziesiętnej (&#38;) i numerycznej szesnastkowej (&#x26;). Pięć zarezerwowanych znaków HTML (<, >, &, ", ') wymaga kodowania za każdym razem, gdy tekst jest wstawiany do HTML. Pozostałe około 2225 encji nazwanych obejmuje symbole, litery z akcentami i litery greckie, ale są opcjonalne, gdy kodowanie dokumentu to UTF-8.

Kiedy używać encji nazwanych, a kiedy numerycznych?

Używaj encji nazwanych, gdy chcesz, aby kod źródłowy był czytelny (programista przeglądający &copy; w szablonie od razu rozumie). Używaj numerycznych (dziesiętnych lub szesnastkowych), gdy odbiorca jest starszy lub bardziej restrykcyjny — parsery XML, starsze klienty pocztowe i niektóre czytniki kanałów rozpoznają tylko niewielki podzbiór nazwanych encji HTML5, ale wszystkie rozpoznają formy numeryczne. Forma szesnastkowa dominuje w kontekstach związanych z bezpieczeństwem, ponieważ pokrywa się jeden do jednego z notacją punktów kodowych Unicode używaną w dokumentach specyfikacji.

Czy dekodowanie obsługuje encje szesnastkowe jak &?

Tak. Dekoder używa pojedynczego wyrażenia regularnego dopasowującego wszystkie trzy formy encji w jednym przebiegu: &name;, &#NNN; oraz &#xHH;. Dopasowania numeryczne są rozwiązywane przez String.fromCodePoint w podstawie 10 lub 16. Mieszane wejście (nazwane i numeryczne w tym samym ciągu) jest dekodowane poprawnie, a nieznane nazwy pozostają jako tekst dosłowny, więc częściowe wejście jest konwertowane bez strat.

Czy narzędzie jest bezpieczne dla niezaufanych danych wejściowych?

Kodek działa wyłącznie w przeglądarce i nie wysyła danych wejściowych nigdzie. To, czy wyjście jest bezpieczne do osadzenia, zależy od kontekstu. Kodowanie encji obsługuje konteksty treści HTML i wartości atrybutów — przypadek OWASP Reguła nr 1. Konteksty JavaScript (wbudowane procedury obsługi zdarzeń, bloki `<script>`), CSS i URL wymagają własnych reguł kodowania — samo kodowanie encji tam nie wystarczy. Po stronie serwera połącz je z kontekstowym silnikiem szablonów, jak DOMPurify lub automatyczna ucieczka Twojego frameworka.

Kodowanie encji HTML po stronie przeglądarki stoi na granicy między danymi użytkownika a renderowanym HTML. Lokalna konwersja pozwala sprawdzić, co wyemitowałby framework, bez wysyłania oryginalnego tekstu do zewnętrznego narzędzia.