CZĘŚĆ 16
Bezpieczeństwo: ochrona przed XSS
PPrezentacja dla nauczyciela
Dane wprowadzone przez użytkownika w formularzu, odczytane z bazy czy pobrane z ciasteczek mogą zawierać złośliwy kod HTML i JavaScript. Brak odpowiedniego zabezpieczenia przy wyświetlaniu pozwala na przejęcie konta lub kradzież sesji. W arkuszach INF.03 zabezpieczenie przed XSS jest oceniane jako osobne, kluczowe kryterium.
Na czym polega XSS
XSS (Cross-Site Scripting) to wstrzyknięcie kodu JavaScript do strony przez dane od użytkownika. Jeśli komentarz zawiera znacznik script i zostanie wypisany bez zabezpieczenia, przeglądarka wykona ten kod.
Skutki bywają poważne: kradzież ciasteczek sesji, podmiana treści strony, przekierowanie na obcy adres. Wystarczy jedno niezabezpieczone miejsce, żeby cała aplikacja była zagrożona.
Źródłem danych może być formularz, parametr adresu, a nawet zawartość bazy wpisana wcześniej przez innego użytkownika. Dlatego zabezpieczamy dane przy wypisywaniu, a nie tylko przy zapisie.
$komentarz = $_GET['komentarz'] ?? '';
// zle: przegladarka wykona ewentualny skrypt
echo '<div>' . $komentarz . '</div>';
// dobrze: dane staja sie tekstem
echo '<div>' . htmlspecialchars($komentarz, ENT_QUOTES, 'UTF-8') . '</div>';
htmlspecialchars i kontekst wypisania
htmlspecialchars() zamienia znaki <, >, cudzysłowy i ampersand na encje. Przeglądarka pokazuje wtedy tekst, a nie wykonuje znaczników.
Używamy flag ENT_QUOTES i kodowania UTF-8. Wartość musi być zabezpieczona także w atrybutach HTML, np. w value="...", bo cudzysłów może zamknąć atrybut.
W kontekście JavaScriptu lub adresu URL potrzebne są inne funkcje, np. json_encode() czy urlencode(). Zasada jest jedna: zabezpieczenie zależy od miejsca wypisania.
$imie = $_GET['imie'] ?? '';
echo '<p>Witaj, ' . htmlspecialchars($imie, ENT_QUOTES, 'UTF-8') . '</p>';
echo '<input type="text" value="' . htmlspecialchars($imie, ENT_QUOTES, 'UTF-8') . '">';
echo '<a href="szukaj.php?q=' . urlencode($imie) . '">Szukaj</a>';
Zasady bezpiecznego wypisywania
Najprostsza zasada: każdą wartość spoza skryptu wypisujemy przez funkcję zabezpieczającą. Dotyczy to również danych z bazy, bo mogły zostać zapisane wcześniej przez innego użytkownika.
Nie warto polegać na „oczyszczaniu” danych przy zapisie i wypisywaniu surowych wartości. To, co jest bezpieczne w bazie, może być niebezpieczne w innym kontekście HTML.
Dobra praktyka to jedna funkcja pomocnicza, np. e($tekst), używana w całym projekcie. Wtedy nie ma miejsca na zapomnienie i łatwo sprawdzić kod przeglądem.
function e($tekst) {
return htmlspecialchars((string) $tekst, ENT_QUOTES, 'UTF-8');
}
$komentarz = $_GET['komentarz'] ?? '';
echo '<p>' . e($komentarz) . '</p>';
echo '<p>' . e('Wiadomosc zapisana') . '</p>';
Ćwiczenia
- 1Pierwszy htmlspecialcharspierwszy htmlspecialcharsZadanie i podpowiedzi →
- 2Znaki mniejszości i encjeznaki mniejszości i encjeZadanie i podpowiedzi →
- 3Zabezpieczenie formularza POSTzabezpieczenie formularza POSTZadanie i podpowiedzi →
- 4Fraza z adresu GETfraza z adresu GETZadanie i podpowiedzi →
- 5Dane z bazy Stored XSSdane z bazy Stored XSSZadanie i podpowiedzi →
- 6Wielopolowe zabezpieczeniewielopolowe zabezpieczenieZadanie i podpowiedzi →
- 7Atrybut value i ENT_QUOTESatrybut value i ENT_QUOTESZadanie i podpowiedzi →
- 8Zdarzenie w atrybuciezdarzenie w atrybucieZadanie i podpowiedzi →
- 9htmlspecialchars zamiast strip_tagshtmlspecialchars zamiast strip_tagsZadanie i podpowiedzi →
- 10Kolejność nl2br i encjikolejność nl2br i encjiZadanie i podpowiedzi →
- 11Weryfikacja linku w hrefweryfikacja linku w hrefZadanie i podpowiedzi →
- 12Pętla po danych z bazypętla po danych z bazyZadanie i podpowiedzi →
- 13Własna funkcja pomocniczawłasna funkcja pomocniczaZadanie i podpowiedzi →
- 14Wypełnienie formularza po błędziewypełnienie formularza po błędzieZadanie i podpowiedzi →
- 15Zabezpieczenie ciasteczka COOKIEzabezpieczenie ciasteczka COOKIEZadanie i podpowiedzi →
- 16Karta ogłoszenia synteza XSSkarta ogłoszenia synteza XSSZadanie i podpowiedzi →