Security Notes

Security considerations for wpzylos-database.

This is critical. Database vulnerabilities lead to data theft.

SQL Injection Prevention

Always Use Prepared Statements

// Bad: VULNERABLE: Direct interpolation
$db->query("SELECT * FROM users WHERE id = {$_GET['id']}");

// Bad: VULNERABLE: String concatenation
$db->query("SELECT * FROM users WHERE name = '" . $name . "'");

// Good: SAFE: Connection auto-prepares when args provided
$db->query(
    "SELECT * FROM users WHERE id = %d",
    absint($_GET['id'])
);

QueryBuilder Auto-Prepares

// QueryBuilder handles preparation automatically
$builder->where('id', $_GET['id'])->first();
// Internally uses: WHERE id = %s or %d

Table Name Injection

Whitelist Table Names

Table names can't use %s placeholders:

// Bad: VULNERABLE: User controls table name
$table = $_GET['table'];
$db->query("SELECT * FROM {$table}");

// Good: SAFE: Whitelist approach
$allowed = ['users', 'posts', 'comments'];
$table = in_array($_GET['table'], $allowed, true)
    ? $_GET['table']
    : 'users';

Use Context for Tables

// Always use context for your tables
$table = $context->tableName('users');
// Returns: wp_myplugin_users

Column Name Injection

Whitelist Order/Sort Columns

// Bad: VULNERABLE
$column = $_GET['orderby'];
$db->query("SELECT * FROM users ORDER BY {$column}");

// Good: SAFE
$allowed = ['name', 'created_at'];
$column = in_array($_GET['orderby'], $allowed, true)
    ? $_GET['orderby']
    : 'created_at';

Security Checklist

  • All WHERE values use prepared statements
  • All INSERT/UPDATE values use prepared statements
  • Table names are whitelisted, not user-controlled
  • Column names are whitelisted for ORDER BY
  • LIMIT/OFFSET values are cast to integers
  • No raw user input in queries