Lesson Notes

OWASP Top 10: Injection Attacks

Module 4: Common Vulnerabilities. SQLi on unencrypted DBs.

Module 4: OWASP Top 10 — Injection: Comprehensive Theory

Injection has been at or near the top of the OWASP Top 10 for years. It occurs when an application takes untrusted input—from a user, a request parameter, or another source—and passes it to an interpreter (a database engine, the operating system shell, an LDAP server, or similar) as part of a command or query. The interpreter cannot tell the difference between intended code and attacker-supplied data, so it executes the attacker's input as code. The result can be data theft, authentication bypass, or full system compromise. This lesson explains in detail how SQL injection and related injection types work, why unencrypted database traffic amplifies impact, and the defenses: parameterized queries (prepared statements) and input validation. Practice only in a controlled lab (e.g. DVWA) on systems you are authorized to test.

How SQL Injection Works: Concatenation and Code vs Data

A vulnerable application often builds a SQL query by concatenating user input into a string. Example: the developer writes query = "SELECT * FROM users WHERE id = '" + userInput + "'". If userInput is the string 1, the query is SELECT * FROM users WHERE id = '1', which is correct. But if the attacker sends userInput = ' OR '1'='1, the query becomes SELECT * FROM users WHERE id = '' OR '1'='1'. The condition '1'='1' is always true, so the query may return every row in the users table (authentication bypass or data leak). The root cause is that the input is embedded into the query string and thus becomes part of the SQL syntax—the database does not treat it as a single literal value. Attackers can go further: UNION SELECT to pull data from other tables; stacked queries (; DROP TABLE users;) if the driver allows multiple statements; or, on some databases, use built-in functions to read files or execute OS commands. Every place user input is concatenated into SQL is a potential injection point (WHERE, ORDER BY, table/column names, etc.).

Other Injection Types: Command, LDAP, and Template

The same pattern applies to other interpreters. Command injection: the app builds an OS command string that includes user input (e.g. ping " + userInput). An attacker can break out of the intended argument and run arbitrary commands (e.g. ; cat /etc/passwd). LDAP injection: user input is concatenated into an LDAP search filter; special characters can change the filter logic and expose or modify directory data. Template injection (e.g. in Jinja2, Freemarker): user input is passed into a template engine; if the engine evaluates expressions, the attacker can execute code on the server. In every case, the fix is to never treat user input as code—use parameterized APIs, allowlisted values, or safe escaping that the interpreter treats as data only.

Unencrypted Database Traffic and Impact

When the application server connects to the database over an unencrypted channel (plain TCP, no TLS), every query and result travels over the network in cleartext. An attacker with network access (same segment, MITM, or compromised router) can capture this traffic with Wireshark or similar. They see the exact SQL (including injected payloads) and the full result sets—passwords, PII, or other sensitive data. So even if the injection is "blind" from the web app (no direct output), the network capture may reveal everything. Encrypting the database connection (TLS between app and DB, or DB-native encryption like PostgreSQL's sslmode) protects confidentiality in transit: the eavesdropper sees only ciphertext. Encryption does not fix the injection vulnerability—the app still must use parameterized queries—but it reduces the impact of a network-level attacker and is part of defense in depth. In your lab, you can demonstrate this by capturing traffic with and without TLS to the DB.

Defenses: Parameterized Queries and Input Validation

Parameterized queries (prepared statements) are the primary defense. The application sends the query structure and the user input separately. Example: "SELECT * FROM users WHERE id = ?" with parameter 1 or '1' OR '1'='1. The database driver binds the parameter as a single value; the string '1' OR '1'='1 is never parsed as SQL. So injection is impossible at that bound parameter. Use parameterized queries for every user-supplied value (numbers, strings, dates). Input validation (allowlists, length limits, type checks) is a second layer: reject input that cannot be valid (e.g. letters when only digits are expected), and sanitize or reject known dangerous patterns. Never rely on validation alone to prevent injection—always use parameterized queries or safe APIs. Principle: never concatenate user input into commands or queries; use least privilege for the DB user. Next: XSS and CSRF, which abuse browser and session trust rather than backend interpreters.

Key Takeaway for Lesson 13

Injection occurs when untrusted input is interpreted as code by a database, shell, LDAP, or template engine. SQL injection is caused by concatenating input into query strings; parameterized queries prevent it by sending input as data. Unencrypted DB traffic allows network eavesdroppers to see queries and results, worsening impact; encrypt DB connections and fix injection. Defend with parameterized queries first, then input validation. Next: XSS and CSRF.