• Strona główna
  • Curriculum Vitae
  • O mnie
  • Przykład: Gramatyka w PHP
  • Przykład: Kompresja CSS
  • Przykład: Kompresja JavaScript
  • Przykład: Skracanie linków
  • Przykład: Wykrywanie serwera HTTP
  • Przykład: Własna bramka SMS
  • Mapa strony
  • Kontakt
Niebieski Pomarańczowy Zielony Różowy Fioletowy

HTML Purifier – ochrona przed XSS

Opublikowane 4 stycznia 2011. Autor: Kamil Brenk. Wizyt: 4 147.

Kategorie: PHP
Tematyka: bezpieczeństwo stron www, biblioteki PHP, optymalizacja serwisów, praktyczne skrypty, wydajność serwisów internetowych

sty 04

Jeszcze kilka dni temu pisałem o atrybucie httpOnly dla ciasteczek, dzięki któremu częściowo (minimalnie) możemy się zabezpieczyć przed atakami typu XSS, czyli przed wstrzykiwaniem niebezpiecznego kodu do naszej strony.

Dzisiaj uderzymy w temat z nieco innej strony, mowa bowiem o filtrowaniu danych wchodzących do aplikacji przy pomocy świetniej biblioteki, HTML Purifier.

Czym jest HTML Purifier?

Jest to biblioteka, która oczyszcza kod HTML ze wszelkich brudów – niedozwolonych przez programistę czy niezgodnych ze specyfikacją W3C elementów i atrybutów HTML. Ponadto biblioteka ta pozwala na definiowanie własnych filtrów, co czyni ją bardzo rozszerzalną.

Przykładowo: mamy formularz WYSIWYG na komentarze od użytkownika. Użytkownik tworzy swój kod HTML, dodając tabelki, obrazki, filmiki z YouTube, etc. Kod taki następnie trafia pod HTML Purifier, w którym możemy wywalić tabelki, a dodatkowo utworzyć filtr, który pobierze wszystkie obrazki na nasz serwer i jednocześnie podmieni adresy URL obrazków na nowe.

Wszystko to w kilkunastu linijkach kodu – nie musimy się także martwić nieprawidłowym kodem HTML czy próbą przeprowadzenia ataku XSS – HTML Purifier zajmie się tym za nas.

Przykładowe użycie

HTML Purifier można konfigurować na wiele różnych sposobów – możliwości konfiguracyjnych jest naprawdę wiele.

W większości przypadków wystarczy jednak domyślna konfiguracja, którą sam najczęściej też wykorzystuję w swoich projektach, tzn. :

1
2
3
4
5
6
$config = HTMLPurifier_Config::createDefault();
$config->set('Attr', 'EnableID', true);
           
$purifier = new HTMLPurifier($config);
           
$html_code = $purifier->purify($html_code);

Nie wiem dlaczego w domyślnym ustawieniu usuwany jest atrybut ID z elementów HTML, niemniej powyższe ustawienia przywraca możliwość stosowania identyfikatorów.

Oczywiście mamy mnóstwo innych opcji konfiguracyjnych. Możemy oczyszczać kod wyjściowy (Tidy HTML w trzech poziomach: light, medium oraz heavy):

1
$config->set('HTML.TidyLevel', 'heavy');

ustawiać odpowiedni element Doctype dokumentu HTML i formatować dokument zgodnie z jego założeniami:

1
$config->set('HTML.Doctype', 'XHTML 1.0 Strict');

czy też definiować atrybuty i ich dopuszczalne właściwości.

Jak widać, możliwości jest wiele, a to tylko niewielki ułamek tego co potrafi ten kombajn. Więcej możemy odnaleźć w dokumentacji, stworzonej zarówno dla użytkownika, jak i dla robotów lubiących czytać dokumentację wygenerowaną przez Doxygen-a :D

Warto też zapoznać się z dokumentem prezentującym skuteczność biblioteki w obronie przeciwko atakom typu XSS: HTML Purifier XSS Attacks Smoketest.

Podsumowanie

HTML Purifier zapewnia wsparcie dla UTF-8, a nawet HTML5. Kod źródłowy jest otwarty dla każdego developera (rozprowadzany na licencji LGPL), biblioteka jest wciąż rozwijana, zapewnia wsparcie dla CSS i długo jeszcze można by wypisywać kolejne zalety.

A wady? Jak na razie nie udało mi się ich znaleźć. Czasem uciążliwe bywa dodawanie obsługi niestandardowych atrybutów HTML. Ponadto taki kombajn zużywa sporo pamięci procesora, niemniej ilekroć przepuszczamy HTML przez takie narzędzie? W moim przypadku bywa to nieczęsto – a jeśli często to korzystam z buforowania i problem rozwiązany.

I na sam koniec warto wspomnieć, że z biblioteki korzysta też wielu dobrych graczy, np. :

  • Yii Framework
  • Lion PHP Framework
  • ImpressCMS
  • Tiki Wiki CMS Groupware
  • Midgard

Stanowi to solidne potwierdzenie tego, iż biblioteka HTML Purifier jest naprawdę warta uwagi.

Komentarze (7)

  1. Tomasz Kowalczyk 4 stycznia 2011

    Jako lepszy kolega biblioteki Tidy w PHP, na pewno zostanie przeze mnie wypróbowany. Dzięki za informacje!

  2. Krzysztof Kotowicz 4 stycznia 2011

    IDki są domyślnie wyłączane przez HTMLPurifiera prawdopodobnie dlatego, że w przypadku zagnieżdżenia strony w można je wykorzystać do wyciągnięcia informacji z atakowanej strony.

    Działa to tak:

    [iframe src=http://atakowana-strona.pl#jakis_konkretny_id]

    i potem przez wlasciwosc scrollTop na objekcie iframe zczytujesz, czy taki idik wystepuje na stronie (scrollTop > 0) czy nie ( = 0). Atak niby wydumany, ale swego czasu udalo sie zaatakowac jakis system webmailowy i sprawdzic liste maili na okreslone tematy u ofiary.

    Szczegóły są tutaj: http://www.contextis.co.uk/resources/white-papers/clickjacking/Context-Clickjacking_white_paper.pdf

    Ale, umówmy się, ryzyko takiego ataku jest dość małe, więc to raczej „puryzm” autora HTMLPurifiera.

    Z dobrych filtrów przeciwXSSowych warty uwagi jest jeszcze Wibble – powinien być o wiele szybszy od purifiera.

  3. Marcin Kłeczek 4 stycznia 2011

    Atrybut ID jest usuwany, żeby „wesoły hateemelowiec” nie duplikował ID już istniejących (#header) i nie zburzył działania aplikacji korzystającej z odwołań do DOM po ID.

  4. Kamil Brenk 4 stycznia 2011

    @Krzysztof: faktycznie, dość oryginalny sposób ataku i wcześniej się z tym nie spotkałem, więc i sam nie wpadłbym na taki pomysł.

    Pokrewnych dla HTML Purifiera jest kilka, m. in. wspomniany przez Ciebie Wibble czy htmLawed. Opisałem jedynie HTML Purifier, bo tylko z nim mam praktyczne doświadczenie :-) I w sumie wystarczy, choć warto też znać konkurencję.

    @Marcin: masz rację – na stronie może być tylko jeden element o danym identyfikatorze i użytkownik mógłby wprowadzić bałagan dublując ID, nie pomyślałem o tym. U siebie potrzebowałem dopuścić atrybut ID, aby w panelu administracyjnym uprawnione osoby mógły zmieniać zawartość boxów dodając identyfikatory elementów, a następnie za pomocą CSS czy JavaScript dodawać konkretne zachowania/wygląd.

  5. Krzysztof Kotowicz 4 stycznia 2011

    @Marcin

    No tak, to trochę prostsze wytłumaczenie ;) Z tego, co teraz czytam, autorzy dodają też, że dublujące się id psują też walidację (a im na niej b. zależy).

  6. matipl 5 stycznia 2011

    HTML Purifier jest jednym z lepszych rozwiązań, które znam oferujące pełne filtrowanie i nie tylko

  7. majne 11 stycznia 2011

    Swego czasu miałem do czynienia również z ksesem. Jednak HTML Purifier bije go na głowę.
    Jego wadą jest fakt, że czasami potrafi zająć całą dozwoloną pamięć i wywalić php’a. Jednak są to przypadki sporadyczne i dzieją się tylko dla bardzo rozbudowanego html’a (na przykład co poniektórych mailingów htmlowych), aczkolwiek warto mieć ten fakt na uwadze.



Kamil Brenk Blog

PHP, JavaScript, SQL, HTML

  • Informacje o blogu

    Kamil Brenk

    Blog o tworzeniu aplikacji na potrzeby sieci Web.

    Praktyczne przykłady, porady i sztuczki. PHP, SQL, AJAX, JavaScript, HTML i pochodne.

    Kanał RSS

    • Najnowsze
    • Komentarze
    • Popularne
    • Liczniki w CSS
    • Wyprzedaż książek o programowaniu!
    • Niestandardowy placeholder
    • JavaScript w modułach
    • Co dalej z blogiem?
    • Interaktywna mapa w HTML i CSS
    • Olsztyn: Jak wyseparować zawartość zassaną przez file_get_content?
    • ERMLAB: Od czegoś trzeba zacząć :) Wiele osób właśnie stawia na...
    • david: co nalezy wkleić na stronę aby plik ze stylami był ladowany...
    • krynicz: Nie jestem pewien czy dobrze to rozumiem: wpisujemy OG w...
    • yaro: Jak zmienić re_write znak "_" na "-"?
    • Piotr: stworzyłem prostą stronkę w PHP, czy jest możliwość aby...
    • MichalR: Super sprawa... bardzo przydatne.. dzieki i pozdrawiam..
    • Niestandardowe czcionki na stronie
    • Sposoby wczytywania JavaScript
    • Gramatyka w PHP, część 1
    • Umowa i zaliczka dla freelancera
    • Wysyłanie wiadomości SMS w PHP
    • Projekt aplikacji po stronie klienta
    • Własny mechanizm Feed
  • Szukajka
    Wpisz co chcesz wyszukać na stronie…
  • Kategorie
    • Apache
    • Freelancer
    • Front-end Development
    • HTML5 & CSS3
    • Inne
    • JavaScript
    • Książki
    • PHP
    • Po godzinach
    • Pozycjonowanie
    • Protokół HTTP
    • SQL
    • Wyrażenia regularne
  • Moje serwisy
    • Testy zawodowe
    • Miłość, uczucia i seks
  • Czytane blogi
    • Wojciech Sznapka
    • Wojciech Soczyński
    • Michał Wachowski
    • Tomasz Kowalczyk
    • Filip Górczyński
  • Strona główna
  • Curriculum Vitae
  • O mnie
  • Przykład: Gramatyka w PHP
  • Przykład: Kompresja CSS
  • Przykład: Kompresja JavaScript
  • Przykład: Skracanie linków
  • Przykład: Wykrywanie serwera HTTP
  • Przykład: Własna bramka SMS
  • Mapa strony
  • Kontakt

Kamil Brenk © 2010. All rights reserved.

Designed by FTL Wordpress Themes brought to you by Smashing Magazine.

Do góry ∧