Table of Contents

8. Database Safety — Parameterization, Boundaries, and Least Privilege

A database is not just storage.
It is a boundary
— one of the most sensitive in the entire system.

Security comes from treating the database as a separate trust domain,
not an extension of application logic.

The goal is simple:
even if the application misbehaves,
the database should remain safe.

This page introduces the mental model for protecting data through parameterization, boundaries, and least privilege.


1. Parameterization Is Non‑Negotiable

SQL injection is not a theoretical risk.
It is one of the most common and most damaging vulnerabilities.

The only reliable defense is parameterized queries:

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);

Parameterization:

Escaping is not enough.
Sanitization is not enough.
Only parameterization is safe.


2. Never Build SQL by Concatenating Strings

Avoid patterns like:

$sql = "SELECT * FROM users WHERE email = '$email'";

Or:

$sql = "UPDATE posts SET title = '$title' WHERE id = $id";

Even if you “sanitize” the input, string‑built SQL is fragile and error‑prone.

A secure system never mixes:

in the same string.


3. Use Named Parameters for Clarity

Named parameters make queries more readable and less error‑prone:

$stmt = $pdo->prepare('SELECT * FROM posts WHERE author_id = :id');
$stmt->execute(['id' => $userId]);

This improves:

Named parameters are small, but they reduce entire classes of mistakes.


4. Avoid Dynamic SQL Whenever Possible

Dynamic SQL is dangerous because it changes the structure of the query based on input.

Avoid patterns like:

If you must use dynamic SQL:

Dynamic SQL should be rare and carefully controlled.


5. Use the Least Privilege Principle for Database Users

Your application should not connect to the database as a superuser.

Prefer:

A compromised application should not become a compromised database.


6. Separate Read and Write Connections

For larger systems:

This reduces:

Read‑only connections are a powerful safety boundary.


7. Validate Data Before It Reaches the Database

The database is not a validator.
It is a boundary.

Validate:

before the data reaches SQL.

The database should receive only predictable, shaped data.


8. Use Transactions for Consistency and Safety

Transactions protect:

Example:

$pdo->beginTransaction();
// operations
$pdo->commit();

A secure system uses transactions not just for correctness, but for safety.


9. Avoid Exposing Raw Database Errors

Database errors can leak:

A secure system:

Error messages are a boundary.


10. Treat the Database as a Separate Security Domain

The database is not an extension of PHP.
It is a separate system with its own:

Security comes from respecting that separation.


Summary

Database safety is about boundaries, not cleverness.

A secure system:

The database is where truth lives.
Protect it with intention
.


This page describes secure defaults and common practices in modern PHP. It is not a complete security guide, and it does not replace formal audits or framework‑specific documentation. These principles are consistent enough to be useful, but security always requires context, judgment, and ongoing review.