Learn / Security / Lesson 05

Injection and escaping

SQL injection and cross-site scripting are the same mistake in two places, data being read as code, and they have the same cure.

Last updated: 2026-09-19

What it is

Injection happens when text from a user is glued into something that gets executed: a SQL query, an HTML page, a shell command. If the text contains the right characters, it stops being data and starts being instructions.

Why it is a rule

How to do it

SQL: parameters, always

js
db.query(`SELECT * FROM users WHERE email = '${email}'`)

db.query('SELECT * FROM users WHERE email = $1', [email])

The first line is the bug. The second sends the query and the value separately, so the database never reads the value as SQL, whatever it contains. There is no safe way to build the first one by "cleaning" input.

Table and column names cannot be parameters. When one must vary, pick it from a fixed list in the code, never from the request.

HTML: escape on output

Every piece of user text that goes into HTML is escaped for the place it lands.

js
const ESC = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }
const escape = (s) => String(s).replace(/[&<>"]/g, (c) => ESC[c])

Escape first, then format

A Markdown or rich-text renderer should escape the whole source before turning ** into <b>. Then a <script> typed into the source is already harmless text by the time any pattern sees it. Doing it in the other order turns the renderer into an injection door.

Links need a scheme check

<a href="javascript:…"> runs code when clicked, and escaping does not change that. Allow only https:, http:, mailto: and relative links.

Content-Security-Policy as the backstop

A CSP header tells the browser which scripts may run. If an injection gets through, a strict CSP can stop the script from executing. It is a second wall, not a replacement for escaping.

How we do it here

Every database call is parameterised. Every page renderer escapes before it formats, and link targets are limited to safe schemes. This site's Markdown renderer, the one drawing this page, escapes the whole source first.

Benefits

Disadvantages

Checklist

Sources

Read this lesson as Markdown