EXERCISE 1 — String vs numeric context injections ================================================== STRING CONTEXT: WHERE name = 'INPUT' The input sits INSIDE single quotes, so you must first CLOSE the string with a quote, then inject logic. ALWAYS-TRUE INJECTION (input): ' OR '1'='1 Resulting query: WHERE name = '' OR '1'='1' - The leading ' closes the opened string (name becomes ''). - OR '1'='1' is always-true logic -> matches every row. (To also discard a trailing clause you'd use a comment: ' OR '1'='1'-- ) NUMERIC CONTEXT: WHERE id = INPUT The input is NOT quoted — it's a bare number in the query. You inject DIRECTLY, no quote needed. ALWAYS-TRUE INJECTION (input): 5 OR 1=1 Resulting query: WHERE id = 5 OR 1=1 - 1=1 is always true -> the OR makes the whole condition match every row. (Other numeric payloads: 0 OR 1=1 , 5 OR 1=1-- , 5 UNION SELECT ... ) WHY THE NUMERIC CASE NEEDS NO QUOTE: - In string context, the breakout character is the single quote because the developer WRAPPED the value in quotes — you have to get OUT of that string literal to reach code position. - In numeric context there is NO surrounding quote. The value is already in a "bare expression" position in the SQL. So OR 1=1 is parsed as SQL the instant it's concatenated — there is nothing to escape. A quote isn't just unnecessary; it would often CAUSE a syntax error. WHY "WE STRIP QUOTES FROM INPUT" FAILS TO PROTECT THE NUMERIC QUERY: - Stripping/escaping quotes only addresses the STRING-context breakout. The numeric injection 5 OR 1=1 contains NO QUOTE AT ALL — there is nothing for the quote filter to remove. The payload passes straight through and injects. - So an app that "removes single quotes" still has fully injectable numeric parameters (ids, ages, prices, page numbers, sort/limit values). Attackers simply use quote-free payloads (boolean logic, UNION, comments) there. - More generally, quote manipulation is the WRONG defence even for string context: it's fragile (alternate encodings, multi-byte charset tricks, backslash interactions) and it corrupts legitimate data (O'Brien). The real fix removes the entire question of context: PARAMETERIZED QUERIES (Chapter 7) bind the value as data so 5 OR 1=1 is treated as the literal (invalid) number "5 OR 1=1", never as SQL. ONE-LINE TAKEAWAY: Identify the context (quoted = string, bare = numeric); numeric injects with no quote, which is exactly why quote-based "defences" don't work — only parameterization does.