Przejdź do treści

Encje HTML i ochrona przed XSS — jak bezpiecznie wyświetlać tekst na stronie

Redakcja AMKBIT · · 2 min czytania

Dlaczego znak „<” w komentarzu może przejąć konto użytkownika, czym jest atak XSS, jak działa kodowanie encji w PHP i JavaScript i dlaczego kontekst (treść, atrybut, URL, skrypt) zmienia zasady.

XSS (cross-site scripting) to atak, w którym do strony trafia kod JavaScript pochodzący od atakującego — np. wpisany w komentarzu, nazwie użytkownika czy parametrze adresu. Wykonuje się on w przeglądarkach innych osób, z ich uprawnieniami: może odczytać dane, wykonać akcje w ich imieniu albo podmienić treść strony.

Skąd bierze się podatność

Gdy aplikacja wstawia tekst od użytkownika do HTML bez zmian, przeglądarka nie odróżnia go od kodu strony. Komentarz zawierający znacznik z atrybutem zdarzenia (np. obrazek z onerror) zostanie potraktowany jak element strony i uruchomi skrypt.

Kodowanie encji — podstawowa ochrona

Przed wstawieniem tekstu do treści HTML zamienia się znaki specjalne na encje: < → &lt;, > → &gt;, & → &amp;, " → &quot;, ' → &#39;. Przeglądarka wyświetli wtedy znaki dosłownie, zamiast interpretować je jako znaczniki.

PHP: echo htmlspecialchars($tekst, ENT_QUOTES, 'UTF-8'); JavaScript: element.textContent = tekst; // zamiast innerHTML

Jak wygląda zakodowany tekst, sprawdzisz w koderze encji HTML.

Kontekst ma znaczenie

Gdzie trafia tekstCo zrobić
treść elementu HTMLencje HTML
wartość atrybutuencje HTML, atrybut zawsze w cudzysłowie
adres w href/srcsprawdź schemat (tylko http/https), parametry koduj jak URL (zob. kodowanie URL)
wnętrze <script>nie wstawiaj surowego tekstu; przekaż dane jako JSON (np. json_encode z flagami JSON_HEX_TAG)
CSS (style)unikaj wstawiania danych użytkownika

Kodowanie encji nie chroni adresu href przed schematem javascript: — dlatego linki od użytkowników trzeba dodatkowo weryfikować.

Dodatkowe warstwy ochrony

  • Silniki szablonów (np. Twig, Blade, React) domyślnie kodują wyjście — nie wyłączaj tego bez powodu.
  • Content-Security-Policy — nagłówek ograniczający, skąd mogą pochodzić skrypty; utrudnia wykorzystanie błędu.
  • Ciasteczka HttpOnly — skrypt na stronie nie odczyta identyfikatora sesji (zob. też bezpieczne przechowywanie tokenów).
  • Walidacja danych wejściowych — np. numer telefonu tylko z cyfr; wzorce przetestujesz w testerze wyrażeń regularnych (zob. wyrażenia regularne od podstaw). Walidacja nie zastępuje kodowania przy wyświetlaniu.
  • Edytory treści (HTML od użytkownika) — gdy użytkownik może formatować tekst, użyj sprawdzonej biblioteki czyszczącej HTML z listą dozwolonych znaczników, zamiast pisać własne filtry.

Zasada do zapamiętania

Koduj dane przy wyświetlaniu, w kontekście, w którym są wyświetlane — a nie przy zapisie do bazy. Ten sam tekst może trafić do HTML, e-maila, pliku CSV czy API i w każdym miejscu wymaga innego traktowania.

Narzędzia do tego poradnika

XSSbezpieczeństwoHTMLencjePHPJavaScript

Przeczytaj też