05 — Defense Playbook: Parameterized Queries & D3FEND
The Golden Rule: Parameterized Queries
Use parameterized queries in ALL database interactions.
Language Examples
Python (sqlite3)
query = "SELECT * FROM users WHERE username=? AND password=?"
cursor.execute(query, (username, password))
# User input is never concatenated into the query
Java (JDBC)
String query = "SELECT * FROM users WHERE username=? AND password=?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, username);
stmt.setString(2, password);
stmt.executeQuery();
PHP (MySQLi)
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
Node.js (Sequelize ORM)
const user = await User.findOne({
where: { username: username, password: password }
});
// ORM handles parameterization automatically
D3FEND Mitigations
D3-RI: Restrict Input
Validate user input against strict whitelist:
- Search for products: only alphanumeric + spaces
- Email field: valid email format only
- ID field: positive integers only
D3-AS: Application Segmentation
Run database with minimal privileges:
- Web app user: SELECT, INSERT, UPDATE only
- No DELETE, DROP, or ALTER permissions
- No FILE I/O permissions
- This limits damage if SQLi succeeds
D3-AC: Access Control
Principle of least privilege:
- Database service runs as unprivileged user
- No root/system access
- Separate read-only replicas for analytics
Layered Defense
Layer 1: Prevention
├─ Use parameterized queries (mandatory)
├─ Use ORM frameworks (automatic parameterization)
└─ Input validation (defense in depth)
Layer 2: Detection
├─ WAF with SQLi rules
├─ Database activity monitoring
└─ XML/anomaly detection
Layer 3: Containment
├─ Database user with minimal privileges
├─ Network segmentation (database on isolated VLAN)
└─ Encrypted database connections (TLS)
Layer 4: Response
├─ Incident response playbook
├─ Data breach notification procedures
└─ Forensic analysis capability
Read next: 06 Reasoning Walkthrough