Chapter 31 Β· SQL Injection

The Open Door in the Database

Maya, a junior developer at a retail company, discovers that a single unguarded input field has been quietly handing attackers the keys to the entire customer database β€” and that the fix was always just one line of code away.

What's in That Input Field?

Maya's first security code review. Her task: audit the customer lookup page. She opens the source and finds the search function: the application takes whatever the user types into the name field, drops it directly into a SQL query, and sends it to the database. SELECT * FROM customers WHERE name = '[user input]'. "That's fine," she thinks β€” until her senior developer Raj stops by her desk and asks: "What stops someone from typing SQL instead of a name?"

She stares at the code. Nothing. There are no checks, no filters, no validation. The application trusts everything the user types and passes it straight to the database engine. "The browser is just the front end," Raj explains. "Behind it is a database that speaks SQL. If your app doesn't filter the input, the user can speak directly to the database β€” and the database will listen."

πŸ’‘ What Makes SQL Injection Possible SQL injection is enabled by poor programming β€” specifically, failing to validate, filter, or escape user input before incorporating it into a database query. The application's job is to treat user input as data. When it treats it as code instead, the attacker speaks directly to the database engine.

How the Injection Works

Raj pulls up the database query on the whiteboard. Normal usage: a user types "Professor" and the app sends SELECT * FROM users WHERE name = 'Professor' β€” the database returns that user's record. Fine. Expected. Now Raj writes a different input: Professor' OR '1'='1. "Watch what the query becomes," he says.

The app constructs: SELECT * FROM users WHERE name = 'Professor' OR '1'='1'. Maya's eyes widen. 1 does equal 1 β€” always. The condition is always true. The database returns every row in the users table. Every account. Every record. "You didn't write any extra software," Raj says. "You didn't exploit a network protocol. You just typed something into an input field. That's all SQL injection is β€” adding your own SQL into the query the application was already going to run."

He writes more examples on the board. With a carefully crafted input, an attacker can add a semicolon and chain additional SQL commands. They can call DROP TABLE customers and delete the entire table. They can call INSERT to add fake records. They can call stored procedures that run administrative commands. "Once the injection works," Raj says, "you effectively have complete control of the data in that database."

πŸ’‘ The OR 1=1 Signature The clause OR '1'='1' (or OR 1=1) in a database query is a near-certain sign of SQL injection. Because 1 always equals 1, this condition makes the WHERE clause always true β€” returning every row in the table rather than the intended filtered result. It is one of the most recognizable SQL injection patterns.

More Than Just Viewing Data

Maya asks: "So the worst case is someone reads customer names?" Raj shakes his head. "The database doesn't just hold names. It holds everything." He lists what the retail company's database contains: full customer profiles, email addresses, shipping addresses, order histories, payment method references, internal employee records, product pricing, vendor contracts, promotional codes. "SQL injection doesn't give read-only access. Depending on what commands the attacker injects and what permissions the database account is running under, they can read it, change it, or delete it."

He describes four outcomes. View: the attacker reads data they were never supposed to see β€” customer PII, credentials, financial records. Modify: the attacker changes records β€” prices, account balances, access levels. Delete: the attacker destroys data β€” a full DROP TABLE wipes the database permanently. Deny: the attacker causes the database to crash or become unresponsive, taking the application down. "One unguarded input field," Raj says. "Four catastrophic outcomes."

πŸ’‘ The Four Outcomes of SQL Injection A successful SQL injection can result in: (1) View β€” unauthorized data disclosure of any record in the database; (2) Modify β€” changes to records, prices, or access levels; (3) Delete β€” destruction of data including entire tables; (4) Deny β€” crashing or rendering the database unavailable. The attacker's reach depends on the permissions of the database account the application uses.

Every Input Is a Potential Door

Raj and Maya walk through the application together. He points out every place where user input touches the database: the login form (username and password fields), the product search bar, the customer registration form (name, address, email), the account lookup field in the admin panel, the URL parameters in product detail pages. "Every one of these is a potential injection point," he says. "An attacker tests them all. They look for the one that isn't sanitized."

Maya is alarmed. "Doesn't this require special software? Do they need to be on the network?" Raj shakes his head. "No. All of this runs through a web browser. The attacker opens the site in their browser, finds an input field, and types SQL. That's the entire attack. No special tool required. No network access required. No user needs to click anything. The only thing standing between the attacker and the database is whether your code checks the input β€” and right now, ours doesn't."

πŸ’‘ Low Barrier, High Impact SQL injection is one of the easiest attacks to execute. It requires only a web browser and knowledge of SQL syntax. No additional software, no special network position, no victim interaction. The attacker simply types crafted input into a form field that the application passes to the database. Yet its impact β€” total database exposure β€” is among the most severe in web application security.

Parameterized Queries β€” The Right Way to Build SQL

Maya asks the question that matters: "How do we fix it?" Raj sits down and shows her. The core problem is string concatenation β€” building SQL by pasting user input directly into the query string. The fix is parameterized queries, also called prepared statements. Instead of building the SQL string with user input embedded in it, the developer writes the query with a placeholder β€” a parameter β€” and then passes the user's input separately. The database engine receives the structure and the data as two separate things. It cannot confuse one for the other.

He writes both versions. Vulnerable: query = "SELECT * FROM users WHERE name = '" + userInput + "'". Safe: the query is defined first as a template β€” SELECT * FROM users WHERE name = ? β€” and then the value of userInput is bound to that placeholder as pure data. The database engine sees the structure defined by the developer and the data provided by the user as completely separate entities. No matter what the user types β€” even Professor' OR '1'='1 β€” it is treated as a literal string being searched for, not as SQL code to execute.

"This is the most important fix," Raj says, "but not the only layer." He walks Maya through the full defense stack: input validation (only accept the character types the field should receive β€” a name field should reject apostrophes and semicolons); stored procedures that limit what SQL operations can be performed; principle of least privilege (the database account the app uses should only have SELECT permission where SELECT is all it needs β€” it should never need DROP TABLE from a customer search); and a web application firewall that can detect and block common injection patterns at the network layer.

βœ… The Defense Stack Against SQL Injection (1) Parameterized queries β€” separate SQL structure from user data; the single most effective control. (2) Input validation β€” reject characters that don't belong in the field. (3) Stored procedures β€” limit what SQL operations are available to the application. (4) Least privilege β€” the database account the application runs under should have only the permissions it actually needs. (5) Web application firewall (WAF) β€” detect and block injection patterns at the network boundary.