EXERCISE 2 — Why hiding DB errors helps but doesn't fix SQLi ============================================================= WHY HIDING ERRORS IS GOOD PRACTICE: - Verbose database errors shown to users LEAK valuable information: * the DB engine and VERSION (e.g. MySQL 8.0.32), * TABLE and COLUMN names and types, * the QUERY STRUCTURE / where the injection landed, * and, with error-based techniques, EXTRACTED VALUES forced into the error text. - This is a genuine information disclosure that accelerates an attack and enables ERROR-BASED extraction. So you SHOULD show users a GENERIC error ("Something went wrong") and log the detailed error SERVER-SIDE only. It's correct hygiene that slows attackers and removes one easy channel. WHY IT IS NOT A FIX FOR SQLi: - Hiding errors changes only the OUTPUT CHANNEL, not the VULNERABILITY. The query is still built by concatenation and is still injectable — the attacker's input is still parsed as SQL. You've removed a convenient READOUT, not the bug. - The injection still SUCCEEDS: an attacker can still bypass auth, run UNION SELECT (if results are shown), modify/destroy data, etc. Only the error-based READBACK is gone. EXACTLY WHAT IT CHANGES FOR THE ATTACKER: - It DOWNGRADES ERROR-BASED in-band SQLi to BLIND SQLi. Instead of reading data straight out of an error message, the attacker switches to INFERENCE: * boolean-based: inject conditions and watch whether the page/results change ( ' AND 1=1-- vs ' AND 1=2-- ), extracting data one character at a time; * time-based: use SLEEP/IF to read answers from response timing when even the page is identical. - If UNION-based output is also available, they may not even need errors. So the attacker simply changes TECHNIQUE; the data still comes out, just slower. WHY THE UNDERLYING VULNERABILITY IS UNCHANGED: - The root cause (Chapter 1) is untrusted input being parsed as SQL CODE due to query construction by concatenation. Suppressing error display does nothing to that: the code/data boundary is still broken at query-build time. You've muted a symptom, not removed the cause. - Channel-closing defences (hide errors, normalize responses) are a whack-a-mole: each one just pushes the attacker to a different SQLi TYPE (error -> boolean -> time -> out-of-band). The vulnerability persists through all of them. THE ACTUAL FIX: - Target the CAUSE with PARAMETERIZED QUERIES (Chapter 7): the input is bound as DATA and never parsed as SQL, so the injection can't happen at all — and therefore there's nothing to read back through ANY channel (error, union, boolean, time, or OOB). Hiding errors is a useful defence-in-depth layer on top, never a replacement. ONE-LINE TAKEAWAY: Hide DB errors for hygiene/info-leak reasons, but know it only converts error-based SQLi to blind SQLi — the injectable query remains; only parameterization removes it.