XSS from a backend's point of view

Backend security Junior Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Predict the output

What does html.escape turn the payload into?

Python 3.13
import html

print(html.escape('<img src=x onerror=alert(1)>'))

Options
Hint 1 of 1

What do < and > become?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A &lt;img src=x onerror=alert(1)&gt;

Correct. Angle brackets become entities, so the browser shows text.

Escaping turns the characters that start HTML, like < and >, into entities. The browser shows the text instead of parsing a tag, so onerror never runs.

Why not the others?
  • B <img src=x onerror=alert(1)>. escape replaces < and >.
  • C An empty string. It encodes; it doesn't strip.
  • D img src=x onerror=alert(1). Characters are encoded, not removed.

30-second answer

Treat all user content as data, never markup: encode it for the context where it lands (HTML body, attribute, URL, JavaScript), or let a templating engine with auto-escaping do it. If you must accept rich text, sanitise it with a maintained allow-list sanitiser on output. Send a Content Security Policy that blocks inline scripts, return JSON with Content-Type: application/json, and keep session cookies HttpOnly so a slip doesn't hand over sessions.

Practise saying it · 30 s. No recording, just a timer

Backend and XSS.

Say your answer out loud, then check which of these points you covered:

  • Encode per context
  • Auto-escaping templates
  • Sanitise rich text
  • CSP
  • HttpOnly cookies

Deep dive

Encoding is context-specific; HTML-escaping isn't enough inside a script tag or URL.

Stored XSS (saved in your database) hits every viewer, so admins are prime targets.

Don't build HTML in strings in API responses.

CSP report-only mode helps you roll it out.

Common mistakes

  • Sanitising on input once and trusting it forever.
  • Disabling template auto-escaping for convenience.
  • Serving user uploads from your main domain.

Senior take & follow-ups

Encode by context, sanitise rich text, CSP, HttpOnly, separate upload domain.

Follow-up questions

Think of your answer first, then open the hint.

  1. Why serve uploads from another domain?

    Show hint

    An uploaded HTML or SVG file can't run scripts with your cookies.

  2. What does CSP add?

    Show hint

    A second line: injected inline scripts don't run.

Suggest a fix if something here is wrong or out of date.