0Pricing
Frontend Academy · Lekcja

Zapobieganie XSS: kodowanie danych wyjściowych i CSP

Pozna Pan/Pani ataki XSS odzwierciedlone, przechowywane i oparte na DOM, będzie kodować dane wyjściowe kontrolowane przez użytkownika, unikać innerHTML z niezaufanymi danymi i doda nagłówek Content Security Policy.

Zapobieganie XSS: kodowanie danych wyjściowych i CSP to bezpłatna lekcja Frontend Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Frontend Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Frontend Academy zawiera 4 lekcji w sumie.

Czym jest XSS?

Cross-Site Scripting występuje, gdy atakujący wstrzykuje wykonywalny kod JavaScript do strony. Przeglądarka uruchamia go z uprawnieniami właściwymi dla źródła strony — może to prowadzić do kradzieży plików cookie, przejęcia sesji, zmiany wyglądu strony lub przekierowania do złośliwego oprogramowania.

Trzy odmiany XSS

Stored: złośliwy skrypt jest zapisywany w bazie danych i wysyłany każdemu odwiedzającemu. Reflected: dane wejściowe są zwracane w odpowiedzi (?q=<script>...). DOM-based: kod JavaScript po stronie klienta zapisuje niezaufane dane w DOM.

Główna przyczyna: innerHTML z niezaufanymi danymi

Używanie innerHTML (lub v-html, dangerouslySetInnerHTML) z ciągami znaków kontrolowanymi przez użytkownika jest najczęstszym wektorem XSS.

// BAD: user input rendered as HTML
el.innerHTML = userComment;  // attacker submits <img onerror=alert(1)>

// Vue equivalent:
<div v-html="userComment"></div>  // same bug

// React equivalent:
<div dangerouslySetInnerHTML={{ __html: userComment }} />  // same bug

Kodowanie danych wyjściowych (bezpieślna wartość domyślna)

Niezaufane ciągi znaków należy traktować jako tekst, a nie HTML. React, Vue, Angular i Svelte domyślnie robią to w interpolacji {value}.

// SAFE: text content, not HTML
el.textContent = userComment;  // <script> shows as literal text

// React (auto-escaped):
<div>{userComment}</div>

// Vue (auto-escaped):
<div>{{ userComment }}</div>

Sanityzacja, gdy konieczne jest renderowanie HTML

Jeśli rzeczywiście trzeba renderować HTML użytkownika, na przykład w edytorach tekstu sformatowanego, należy przeprowadzić sanityzację za pomocą DOMPurify — nigdy nie należy tworzyć własnego sanityzatora opartego na wyrażeniach regularnych.

import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(userHtml);
el.innerHTML = clean; // strips <script>, on* handlers, dangerous URLs

Weryfikowanie adresów URL

Adresy URL kontrolowane przez użytkownika w href lub src mogą wywołać XSS za pośrednictwem schematów javascript:.

// BAD:
<a href={userUrl}>Click</a>
// attacker submits: javascript:alert(1)

// GOOD: whitelist protocols:
function safeUrl(url) {
  if (!/^https?:\/\//.test(url) && !url.startsWith('/')) return '#';
  return url;
}

Content Security Policy (CSP)

CSP to nagłówek odpowiedzi HTTP informujący przeglądarkę, z jakich źródeł wolno ładować skrypty, style, obrazy i inne zasoby. Nawet jeśli atakujący wstrzyknie skrypt, przeglądarka odmówi jego uruchomienia.

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:

Rygorystyczne CSP z nonce

W przypadku kontrolowanych skryptów umieszczanych bezpośrednio w dokumencie należy używać nonce generowanego dla każdego żądania. Skrypty wstrzyknięte przez atakującego nie będą miały pasującego nonce.

// Server generates a random nonce per request:
const nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy', `script-src 'nonce-${nonce}' 'strict-dynamic'`);

// Inject into the HTML:
<script nonce="abc123">/* trusted inline code */</script>

Pliki cookie HttpOnly i Secure

Pliki cookie sesji należy ustawić z atrybutem HttpOnly, aby JavaScript nie mógł ich odczytać — nawet w przypadku XSS atakujący nie będzie mógł pobrać tokenu sesji.

Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict

Integralność zasobów podrzędnych (SRI)

Podczas ładowania skryptów innych firm za pośrednictwem CDN należy używać SRI, aby zweryfikować zgodność zawartości z hashem. Skompromitowany CDN nie może dostarczyć złośliwego skryptu bez spowodowania niepowodzenia weryfikacji hasha.

<script
  src="https://cdn.example.com/lib.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

Trusted Types (eksperymentalne)

Trusted Types to funkcja przeglądarki (opartej na Chromium), która wymusza, aby niebezpieczne miejsca docelowe (innerHTML) otrzymywały obiekt Trusted Type — całkowicie uniemożliwiając wstawianie ciągów znaków.

Testowanie pod kątem XSS

Proszę spróbować wstrzyknąć <img src=x onerror=alert(1)> do każdego pola tekstowego, którego zawartość jest później renderowana. Jeśli zobaczy Pan/Pani alert, oznacza to błąd XSS. Do automatycznego skanowania można użyć narzędzi takich jak OWASP ZAP.

Szybkie sprawdzenie

Dlaczego {userInput} w React jest domyślnie bezpieczne, a dangerouslySetInnerHTML już nie?

Podsumowanie: zapobieganie XSS

Domyślnie należy renderować tekst (Reacta {x} i Vue {{ x }} są bezpieczne). Podczas renderowania HTML należy używać biblioteki DOMPurify. Należy stosować białą listę protokołów URL. Nagłówek CSP (z nonce lub 'strict-dynamic') blokuje wstrzyknięte skrypty. Ciasteczka HttpOnly uniemożliwiają ich kradzież za pomocą JavaScriptu. Dla skryptów z CDN należy używać hashy SRI. Należy testować dane wejściowe za pomocą klasycznych payloadów.

Często zadawane pytania

Czy lekcja „Zapobieganie XSS: kodowanie danych wyjściowych i CSP” jest bezpłatna?

Tak — pełny tekst „Zapobieganie XSS: kodowanie danych wyjściowych i CSP” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Frontend Academy, przejdź na CoddyKit PRO. Kurs Frontend Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Zapobieganie XSS: kodowanie danych wyjściowych i CSP”?

Pozna Pan/Pani ataki XSS odzwierciedlone, przechowywane i oparte na DOM, będzie kodować dane wyjściowe kontrolowane przez użytkownika, unikać innerHTML z niezaufanymi danymi i doda nagłówek Content S… Ćwiczysz Frontend Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Frontend Academy?

Nie wymagamy żadnego doświadczenia. Frontend Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Zapobieganie XSS: kodowanie danych wyjściowych i CSP”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Frontend Academy?

Tak. Każda lekcja Frontend Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Zapobieganie XSS: kodowanie danych wyjściowych i CSP
  2. CSRF: pliki cookie SameSite i tokeny
  3. Content Security Policy: nonce i hash
  4. Przepływy OAuth po stronie frontendu
← Powrót do Frontend Academy