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 bugKodowanie 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 URLsWeryfikowanie 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=StrictIntegralność 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
- Zapobieganie XSS: kodowanie danych wyjściowych i CSP
- CSRF: pliki cookie SameSite i tokeny
- Content Security Policy: nonce i hash
- Przepływy OAuth po stronie frontendu