Vad är Cross-Site Scripting och hur hindrar jag det?

Det här inlägget publicerades ursprungligen på bloggen Entreprenörd 15 december 2009.

Cross-Site Scripting (förkortas XSS) är ett säkerhetshål som tillåter en hacker att injicera Javascript på din webbplats och därigenom komma över andra användares känsliga uppgifter, exempelvis lösenord.

I Wikipedias artikel om Cross-Site Scripting kan vi läsa att XSS har blivit det vanligaste säkerhetshålet över huvud taget för programvara, och att vissa forskare hävdar att 68% av alla webbplatser är öppna för XSS-attacker. Historiskt har både Google (sökmotorn), GMail, Facebook och Wikipedia haft problem med XSS.

Förenklat kan man säga att problemet uppstår när användare tillåts mata in html, som sedan injiceras direkt i din webbplats’ html utan att saneras.

Exempel på Cross-Site Scripting

Ett enkelt exempel är en sökmotor. När sökresultaten visas, brukar även söktermen visas. Låt säga att söktermen visas så här:

<p>Du har sökt på SÖKTERM</p>

Säg nu att du skriver in detta som din sökterm:

<script>alert('Hello, world!');</script>

Om de speciella html-tecknen < och > inte ersätts med html-entiteter, kommer söktermen visas så här:

<p>Du har sökt på <script>alert('Hello, world!');</script></p>

Och alltså kommer ditt Javascript köras (en dialogruta med texten “Hello, world!” visas). Du kan förstås också hänvisa till ett komplett skript på din webbserver.

Med Javascript kan du också läsa besökarens cookies och skicka dem till en annan webbserver med AJAX. Du kan alltså med en länk till ett sökresultat få tillgång till besökares cookies, och om de är inloggade, kan du få tillgång till deras inloggningsuppgifter.

Något åt det här hållet (fast mer komplicerat) råkade Google ut för 2005. Då råkade de ut för den lömska teckenkodningen UTF-7.

Ett mycket värre exempel är om dina användare kan skapa sidor på din webbplats, som andra användare sedan kan se. De matar in Javascript på finurliga sätt, och koden sparas och visas för andra användare. Varje gång sidan visas, skickas användarens cookies till en annan server.

Hur skyddar jag min webbplats?

Det är svårt att helt skydda sig mot Cross-Site Scripting, framförallt om du tillåter viss html eller andra märkspråk som Markdown, Textile eller BBCode.

Men, om du inte tillåter märkspråk i användarinmatad data, kan det räcka med dessa åtgärder:

  1. Sanera alltid data innan det visas med htmlspecialchars($str, ENT_QUOTES, 'UTF-8')
  2. Ange alltid explicit teckenkodning för dina webbsidor, exempelvis UTF-8. Annars kan du också råka ut för UTF-7-hackers.
  3. Se till att session-cookies är bundna till en viss IP-adress, så att de inte kan kapas från en IP till en annan.
  4. Sätt flaggan HttpOnly för cookies, så att Javascript inte kommer åt dem, och de inte kan kapas i webbläsare som stöder flaggan.

Läs mer på exempelvis Chris Shifletts eller Jeff Atwoods bloggar.