flawopen.com/sql-injection-c/Cpp

CWE-89 · Critical
flawopen.com Security Research

SQL Injection in C/C++

Learn how to fix SQL Injection (CWE-89) in C and C++. Side-by-side vulnerable vs secure code examples for sqlite3_prepare_v2 and libpq PQexecParams binding.

💡 Plain English Explainer (ELI5)

Imagine a form that only ever expects a ticket number, like 482. SQL injection is what happens when someone types something sneaky into that box instead of a number — a trick phrase that makes the system say "show me every ticket" instead of just ticket 482, because the system never checked that what it received was actually just a number.

Core Concepts & Subsystem Terms

user-controlled input
Any value that ultimately came from whoever is using — or attacking — the app: a form field, a URL parameter, an uploaded filename, an HTTP header. The app can't assume it's well-formed or safe.
SQL query
The command sent to a database — e.g. "get this row," "delete this table." Its meaning comes entirely from its exact text, which is what makes injecting extra text into it dangerous.

Step-by-Step Attack Flow

Source Code: Flaw vs. Secure Implementation

✕ UNPATCHED FLAW
/* user_id from network input */
char query[256];
sprintf(query,
  "SELECT * FROM users WHERE id = %s",
  user_id);
sqlite3_exec(db, query, cb, 0, &errmsg);
✓ HARDENED SECURE PATCH
/* value bound, never in the query text */
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db,
  "SELECT * FROM users WHERE id = ?",
  -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, user_id,
  -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);

Engineering & System Hardening Checklist

References