Sikau

Security · Day 2 · about 35 min

SQL injection

Why string-built queries are dangerous, and how parameters fix it.

' OR '1'='1

"SELECT * FROM users WHERE name = '" + name + "'" looks fine until someone's name is ' OR '1'='1. Now the query returns everyone. That's SQL injection — still one of the most damaging bugs. The fix: never splice data into code. Use parameters ($1, ?), and let the driver quote values safely.

How a driver quotes

function quote(value) {
  if (value === null || value === undefined) return "NULL";
  if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
  if (typeof value === "number") {
    if (!Number.isFinite(value)) throw new Error("Bad number");
    return String(value);
  }
  if (Array.isArray(value)) return "(" + value.map(quote).join(", ") + ")";
  return "'" + String(value).replace(/'/g, "''") + "'"; // double every quote
}

function format(sql, params) {
  let out = "";
  let used = 0;
  let inString = false;
  for (const ch of sql) {
    if (ch === "'") inString = !inString;
    if (ch === "?" && !inString) {
      if (used >= params.length) throw new Error(`Expected more than ${params.length} parameters`);
      out += quote(params[used++]);
    } else out += ch;
  }
  if (used !== params.length) throw new Error(`Expected ${used} parameters, got ${params.length}`);
  return out;
}

The rest of this lesson

  • Data versus codeexplain
  • Beyond parametersexplain
  • Injectedpredict
  • Injection familymatch
  • Parameterisewrite 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