Publikowanie tego jako skonsolidowanego odniesienia z wersji beta Dokumentacji SO, która przechodzi w tryb offline.
Problem
Skrypty między witrynami to niezamierzone wykonanie zdalnego kodu przez klienta WWW. Każda aplikacja internetowa może narazić się na XSS, jeśli pobierze dane wejściowe od użytkownika i wyśle je bezpośrednio na stronie internetowej. Jeśli dane wejściowe obejmują HTML lub JavaScript, zdalny kod może zostać wykonany, gdy treść ta jest renderowana przez klienta WWW.
Na przykład, jeśli strona zewnętrzna zawiera plik JavaScript:
// http://example.com/runme.js
document.write("I'm running");
A aplikacja PHP bezpośrednio przekazuje ciąg znaków do niej przekazany:
<?php
echo '<div>' . $_GET['input'] . '</div>';
Jeśli niezaznaczony parametr GET zawiera, <script src="http://example.com/runme.js"></script>
dane wyjściowe skryptu PHP będą następujące:
<div><script src="http://example.com/runme.js"></script></div>
Uruchomiony zostanie skrypt JavaScript innej firmy, a użytkownik zobaczy „Uruchomię” na stronie internetowej.
Rozwiązanie
Zasadniczo nigdy nie ufaj wkładowi pochodzącemu od klienta. Każda wartość GET, POST i cookie może być dowolną wartością, dlatego należy ją zweryfikować. Kiedy wypisujesz którąś z tych wartości, unikaj ich, aby nie zostały ocenione w nieoczekiwany sposób.
Należy pamiętać, że nawet w najprostszych aplikacjach dane można przenosić i trudno będzie śledzić wszystkie źródła. Dlatego najlepszą praktyką jest zawsze unikanie wyjścia.
PHP oferuje kilka sposobów na uniknięcie wyjścia w zależności od kontekstu.
Funkcje filtrów
Funkcje filtrowania PHP pozwalają na dezynfekcję lub walidację danych wejściowych do skryptu php na wiele sposobów . Są przydatne podczas zapisywania lub wysyłania danych wejściowych klienta.
Kodowanie HTML
htmlspecialchars
przekonwertuje żadnych „znaków szczególnych html” w ich kodowania HTML, co oznacza, że wtedy nie być przetwarzane w standardzie HTML. Aby naprawić nasz poprzedni przykład przy użyciu tej metody:
<?php
echo '<div>' . htmlspecialchars($_GET['input']) . '</div>';
// or
echo '<div>' . filter_input(INPUT_GET, 'input', FILTER_SANITIZE_SPECIAL_CHARS) . '</div>';
Wyprowadziłby:
<div><script src="http://example.com/runme.js"></script></div>
Wszystko wewnątrz <div>
znacznika nie będzie interpretowane przez przeglądarkę jako znacznik JavaScript, ale jako zwykły węzeł tekstowy. Użytkownik bezpiecznie zobaczy:
<script src="http://example.com/runme.js"></script>
Kodowanie URL
Podczas generowania dynamicznie generowanego adresu URL PHP zapewnia urlencode
funkcję bezpiecznego generowania prawidłowych adresów URL. Na przykład jeśli użytkownik jest w stanie wprowadzić dane, które stają się częścią innego parametru GET:
<?php
$input = urlencode($_GET['input']);
// or
$input = filter_input(INPUT_GET, 'input', FILTER_SANITIZE_URL);
echo '<a href="http://example.com/page?input="' . $input . '">Link</a>';
Wszelkie złośliwe dane wejściowe zostaną przekonwertowane na zakodowany parametr adresu URL.
Korzystanie ze specjalistycznych bibliotek zewnętrznych lub list OWASP AntiSamy
Czasami będziesz chciał wysłać HTML lub inny rodzaj kodu. Będziesz musiał prowadzić listę autoryzowanych słów (biała lista) i nieautoryzowanych (czarna lista).
Możesz pobrać standardowe listy dostępne na stronie OWASP AntiSamy . Każda lista nadaje się do określonego rodzaju interakcji (eBay api, tinyMCE itp.). I to jest open source.
Istnieją biblioteki, które filtrują HTML i zapobiegają atakom XSS w ogólnym przypadku i wykonują co najmniej tak samo dobrze, jak listy AntiSamy z bardzo łatwą obsługą. Na przykład masz HTML Purifier