Academy

Module 4 · SQL Injection in 2026 🔒

Manish Garg
Manish Garg Associate CISSP · RingSafe
April 19, 2026
8 min read
🎯 WEB APP PENTEST PATH
MEDIUM
⏱ 120 min
Module 4 of 8

What you’ll learn

  • How SQL injection actually works at the query-construction level
  • Classic in-band SQLi with UNION-based extraction
  • Blind SQLi (boolean and time-based) — when the response doesn’t tell you what you want
  • Out-of-band SQLi — exfiltration via DNS or HTTP when nothing else works
  • NoSQL injection (MongoDB, Redis) — still a thing in 2026
  • When to use sqlmap, and when it fails
  • Prevention: parameterized queries, stored procedures, ORM pitfalls

Prerequisites: Modules 1–3. Basic SQL reading comprehension (SELECT / WHERE / JOIN).

SQL injection has been on every Top 10 list since OWASP started publishing one in 2003. It’s still on the list in 2026. The 20-year-old basic patterns are largely mitigated in modern frameworks, but the bug persists in three places: legacy code bases with hand-constructed queries, unsafe usage of ORMs that developers trust blindly, and dynamic query building in reporting or admin features where the usual safety rails get bypassed.

A successful SQLi in 2026 typically means one of these: enterprise intranet app on Oracle or SQL Server with stored-procedure bugs, a modern API with a developer-built “flexible filters” feature, or a Python app doing raw cursor.execute(f"SELECT * FROM users WHERE id={user_id}") because they forgot parameterization. This module covers the techniques to find all three.

How SQL injection works

The server has a SQL query template. User input is meant to fill in part of the query, but because the input isn’t properly separated from the query structure, the input can change the structure itself.

# Vulnerable (Python):
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"

# Benign input: username='alice', password='secret'
# Resulting query:
SELECT * FROM users WHERE username = 'alice' AND password = 'secret'

# Malicious input: username="admin' --", password="anything"
# Resulting query:
SELECT * FROM users WHERE username = 'admin' --' AND password = 'anything'
# The -- comments out the rest; admin logs in without a valid password.

The root cause: user input mixed with query structure via string concatenation. The fix: always use parameterized queries — the query template is fixed, and parameters are sent separately and bound to placeholders by the database driver, not the application.

# Safe (Python):
cursor.execute(
    "SELECT * FROM users WHERE username = %s AND password = %s",
    (username, password)
)
# Even if username is "admin' --", the driver treats it as a literal string.

Detection — the basic tests

For every parameter an attacker controls (URL params, POST body, headers, cookies, JSON fields), test:

  1. Append a single quote: '. If the app returns a 500 error, a database error message, or a different response structure, the input is reaching a SQL context.
  2. Append ' OR 1=1 --. If the response set changes (e.g., returning more records), classic SQLi is confirmed.
  3. Append ' AND 1=2 --. Should return zero results. If the response differs from the benign input, boolean-based blind SQLi is in play.
  4. Append ' OR SLEEP(5) -- (MySQL) or equivalent for other databases. If the response takes ~5 seconds, time-based blind SQLi works.

Database-specific syntax:

🔐 Intermediate Module · Basic Tier

Continue reading with Basic tier (₹499/month)

You've read 28% of this module. Unlock the remaining deep-dive, quiz, and every other Intermediate module.

99+ modulesAll levels up to this tier
20-question quizzesUnlimited retries with explanations
Completion certificatesShareable on LinkedIn
18 more sections locked below