Blog
sql
4 min read

Don't Turn Inputs into Queries: Preventing SQL Injection and "Universal Account Lock"

The moment you paste user input into an SQL string, login bypassing and operational failures like "UPDATE all users" can happen at once.

Don't Turn Inputs into Queries: A Single Line that Could Lock All Accounts

The moment you paste user input into an SQL string, login bypassing and operational failures like “UPDATE all users” can happen at once.

Security is not about “cleaning strings,” but about “separating data from the query structure.”


Background/Problem: The Vulnerability of Concatenation

Suppose you have code that finds a user and updates their status to “Locked” by concatenating the username.

javascript
// Dangerous concatenation\nconst query = \"UPDATE users SET status = 'LOCKED' WHERE username = '\" + userInput + \"'\";

If a malicious user enters ' OR '1'='1, the query becomes:

sql
UPDATE users SET status = 'LOCKED' WHERE username = '' OR '1' = '1';

→ Expected Result / What Changed:

Since '1'='1' is always true, every user in the database gets locked at once!


Core Concepts

1) Prepared Statements (Parameterization)

Pass values to the SQL engine as parameters (?), not as parts of the string. This prevents the input from being interpreted as code.

javascript
// Safe approach\nconst query = \"UPDATE users SET status = 'LOCKED' WHERE username = ?\";\ndb.execute(query, [userInput]);

→ Expected Result / What Changed:

Even if the input contains OR '1'='1', it is treated as a literal string value, not a part of the logic. No other accounts are affected.


2) The Principle of Least Privilege

The database account used by the application should only have the minimum necessary permissions. For example, an account only used for reading should not have UPDATE or DELETE rights.


Solution Approach (Security Checklist)

  1. Never concatenate: Eliminate all code that builds SQL strings using + or backticks for user input.
  2. Use ORMs wisely: Most ORMs use prepared statements by default, but “Raw Query” modes can still be vulnerable.
  3. Validation at the Gate: Validate the format and length of user input before it even reaches the database layer.

Implementation (Vulnerable vs. Secure)

Comparison of a dangerous string concatenation and a safe parameterized query:

javascript
// DANGEROUS\ndb.query(`SELECT * FROM users WHERE id = ${id}`);\n\n// SECURE\ndb.query('SELECT * FROM users WHERE id = ?', [id]);

The secure version ensures that id is never executed as SQL logic, even if it contains semicolons, quotes, or keywords.


Reproducing in Next.js (Execution via Button on Client)

javascript
\"use client\"\n\nimport { useState } from 'react';\n\nexport default function SqlInjectionDemo() {\n  const [input, setInput] = useState(\"' OR '1'='1\");\n\n  const showResult = () => {\n    const vulnerableQuery = `UPDATE users SET locked = true WHERE username = '${input}'`;\n    alert(`Executing simulated query:\\n\\n${vulnerableQuery}\\n\\nResult: If successful, ALL USERS would be locked!`);\n  };\n\n  return (\n    <div className=\"p-4 flex flex-col gap-4\">\n      <input value={input} onChange={e => setInput(e.target.value)} className=\"border p-2\" />\n      <button onClick={showResult} className=\"bg-red-500 text-white p-2\">Check Simulated Impact</button>\n    </div>\n  );\n}

This demo provides a safe way to visualize how malicious inputs can fundamentally alter the intended logic of an SQL statement.


Common Mistakes/FAQ

Q1. Is string escaping enough? (e.g., adding backslashes to quotes)

Escaping can be bypassed depending on the character encoding or specific database configuration. Prepared statements are the only 100% reliable defense.

Q2. Does this apply to NoSQL (like MongoDB) too?

Yes! NoSQL databases can also be vulnerable to similar injection attacks if user inputs are directly merged into query objects (e.g., the $where operator).


Summary

  • Never concatenate user input directly into SQL strings.
  • Use Prepared Statements (Parameterization) as the default defense.
  • Follow the principle of least privilege for database accounts.

Conclusion

SQL Injection is an old but still critical vulnerability. By treating all user input as untrusted data and strictly separating it from your query logic, you can prevent catastrophic data breaches and operational failures.


Related Posts