Sikau

Security · Day 1 · about 35 min

Cross-site scripting

Never let text become code: escape output, tag templates, safe URLs.

Think like an attacker

Security starts with a question: *what if the input is hostile?* A café review that says <img src=x onerror="steal(document.cookie)"> becomes code in every visitor's browser if you paste it into HTML — cross-site scripting (XSS). The fix is to treat data as data: escape it for the place it's going.

  • HTML text: escape & < > " '
  • URLs in href: only allow http: and https: (block javascript:)
  • Frameworks like React escape by default — dangerouslySetInnerHTML is named that for a reason

Escaping by default

const ESCAPES = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };

function escapeHtml(value) {
  return String(value).replace(/[&<>"']/g, (c) => ESCAPES[c]);
}

// A tagged template: html`<p>${name}</p>` escapes every interpolated value.
function html(strings, ...values) {
  return strings.reduce((out, s, i) => out + s + (i < values.length ? escapeHtml(values[i]) : ""), "");
}

function safeUrl(url) {
  try {
    const u = new URL(url, "https://sikau.com");
    return u.protocol === "https:" || u.protocol === "http:" ? u.href : "#";
  } catch {
    return "#";
  }
}

The rest of this lesson

  • Context decides the escapingexplain
  • Defence in depthexplain
  • Escaped?predict
  • Safe or dangerous?match
  • Make output safewrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 8 lessons of Security