Atak XSS przy użyciu znaczników script, style i image

Dowiedz się, jak zainfekować stronę za pomocą ataku XSS przy użyciu tagów script, style lub image. Zobacz, jak zastąpić zawartość strony swoją własną, nawet bez JavaScriptu.

Daniel Gustaw

Daniel Gustaw

4 min read

Atak XSS przy użyciu znaczników script, style i image

Artykuł ten opisuje przykłady ataków XSS. Użycie znaczników <script> jest prawdopodobnie najbardziej znanym przypadkiem, ale istnieją również inne możliwości. Możesz zmienić zawartość strony internetowej, używając znacznika <img> lub czystego CSS.

To materiał edukacyjny — pamiętaj, że hakowanie bez zgody właściciela jest nielegalne! :)

Kod strony

Aby zaprezentować atak, tworzymy prostą stronę internetową opartą na PHP. Zazwyczaj oddzielamy logikę od widoku, ale dla uproszczenia i zminimalizowania liczby linii kodu połączyliśmy je, a cały kod strony znajduje się w pliku index.php. Aby uzyskać podatną stronę, musi ona być w stanie zapisywać tekst od użytkownika i wyświetlać go na ekranie bez wcześniejszego filtrowania.

W celu uproszczenia rezygnujemy z bazy danych i używamy pliku JSON. Pierwszym plikiem naszego projektu jest db.json:

db.json

["First comment","Second one"]

Aby zapisać komentarze wysyłane za pomocą skryptu PHP, wykonujemy następujące czynności:

index.php

<?php
$comments = json_decode(file_get_contents('db.json'));

if($_SERVER["REQUEST_METHOD"] === "POST") {
    $comments[] = $_POST["comment"];
    file_put_contents('db.json', json_encode($comments));
}

Niezależnie od metody zapytania, skrypt wyświetla formularz oraz listę komentarzy:

index.php

echo '<form action="" method="post">
    <input type="text" name="comment">
    <input type="submit" value="send">
</form>
<ul>';

foreach ($comments as $comment) {
    echo "<li>".$comment."</li>";
}
echo '</ul>';

Możesz uruchomić serwer za pomocą polecenia:

php -S localhost:8000

Utworzona strona internetowa wygląda następująco:

Strona jest w pełni funkcjonalna — pozwala na dodawanie komentarzy, zapisywanie ich w formacie JSON i wyświetlanie ich listy. Gdyby użytkownicy chcieli dodawać tylko zwykły tekst, na tym moglibyśmy zakończyć. Musimy jednak założyć, że przynajmniej jeden użytkownik będzie chciał przeprowadzić atak. :)

Jak przeprowadzić atak?

Ten przepływ danych — zapisywanie na serwerze i wyświetlanie po stronie klienta — umożliwia przeprowadzenie ataku XSS, jeśli tekst nie zostanie odpowiednio przefiltrowany. XSS (Cross-Site Scripting) umożliwia wstrzyknięcie skryptów po stronie klienta do stron oglądanych przez innych użytkowników.

Dodany kod jest interpretowany przez przeglądarkę, a nie serwer. Nie przejmujemy więc samego serwera, ale kontrolujemy zachowanie przeglądarki klienta. Przykładowe cele atakującego to:

Skrypt może być zapisany w bazie/pliku na serwerze lub przekazany w linku. W naszym przypadku zapisujemy skrypt do pliku db.json poprzez formularz komentarzy. Chcemy zmienić treść strony na “Hacked by Daniel”. Po zastosowaniu każdej z poniższych metod strona będzie wyglądać tak:

Tag Script

Najprostszym sposobem jest dodanie znacznika <script>, który dynamicznie po załadowaniu strony zmienia jej zawartość:

<script>document.querySelector('html').innerHTML="Hacked By Daniel"</script>

Ten kod wybiera element główny html i podmienia całą jego zawartość za pomocą właściwości innerHTML.

Tag Style

Inna metoda działa nawet w sytuacji, gdy tagi <script> są filtrowane, a JavaScript wyłączony w przeglądarce:

<style>html::before {content: "Hacked By Daniel";} body {display: none;}</style>

Zdefiniowaliśmy dwie reguły CSS. Pierwsza dodaje tekst Hacked By Daniel przed elementem body, a druga całkowicie ukrywa oryginalną treść strony (body).

Tag Image

Filtrowanie tagów <script> i <style> w komentarzach nie wystarczy, ponieważ skrypty można uruchamiać również w zdarzeniach innych tagów HTML:

<img src=undefined onerror='document.querySelector("html").innerHTML="Hacked By Daniel"'>

To przykład obrazu z nieprawidłowym adresem URL. Gdy próba załadowania pliku się nie powiedzie, przeglądarka automatycznie wykona kod JavaScript zawarty w atrybucie onerror.

Jak się bronić?

Aby obronić się przed tym atakiem, musimy filtrować dane wejściowe i uciekać (escape’ować) tagi HTML. Możemy to zrobić, modyfikując kod w index.php:

-      $comments[] = $_POST["comment"];
+      $comments[] = htmlspecialchars($_POST["comment"]);

Po zastosowaniu tej poprawki tekst wpisany w formularzu zostanie wyświetlony dosłownie jako zwykły ciąg znaków, a nie zinterpretowany jako kod HTML:

Podsumowanie

Przedstawiliśmy proste przykłady ataków XSS przy użyciu różnych tagów HTML. Nowoczesne frameworki, takie jak Symfony czy Laravel, posiadają wbudowane mechanizmy chroniące przed XSS, ale pisząc w czystym PHP, zawsze należy pamiętać o używaniu funkcji takich jak htmlspecialchars.

Other articles

You can find interesting also.