Security#
Introduction#
DBLayer includes layered SQL safety checks for query text and bindings. Security is configured globally by mode and can be hardened or tuned per connection.
Security Mode#
Available modes:
SecurityMode::OFFSecurityMode::NORMALSecurityMode::STRICT
use Infocyph\DBLayer\Security\Security;
use Infocyph\DBLayer\Security\SecurityMode;
Security::setMode(SecurityMode::STRICT);
Mode Semantics#
OFF: disables automatic SQL validation.NORMAL: injection/binding validation with practical defaults.STRICT: adds more aggressive pattern checks and tighter policies.
Policy Guardrails#
SecurityMode::OFFis blocked by default.security.enabled = falseis blocked unless you setsecurity.allow_insecure = true.Intentional global override for advanced local diagnostics:
use Infocyph\DBLayer\Security\Security;
Security::allowInsecureMode(true);
Validation Coverage#
SQL injection pattern checks
Query length checks
Parameter count and size checks
Additional dangerous-pattern scans in strict mode
The validator is defense-in-depth. You should still use parameterized queries and avoid concatenating untrusted input into SQL fragments.
Per-Connection Security Config#
'security' => [
'enabled' => true,
'max_sql_length' => 8000,
'max_params' => 500,
'max_param_bytes' => 4096,
'queries_per_second' => 0,
'queries_per_minute' => 0,
'rate_limit_key' => null,
'rate_limit_callback' => null,
'strict_identifiers' => true,
'require_tls' => null,
'allow_insecure' => false,
'raw_sql_policy' => 'allow',
'raw_sql_allowlist' => [],
]
Transport / TLS Policy#
security.require_tls = trueenforces TLS for MySQL/PostgreSQL.security.require_tls = falserequiressecurity.allow_insecure = true.DB::hardenProduction()setsrequire_tls = truefor hardened defaults.
Driver requirements:
MySQL: provide secure transport via
ssl_ca/ssl_cert/ssl_keyor a securesslmode.PostgreSQL: set
sslmodetorequire,verify-ca, orverify-full.
Raw SQL Fragment Policy#
Raw entry points (for example whereRaw(), selectRaw(), string
fromSub(), and string CTE bodies) are controlled by:
raw_sql_policy = allow: default behavior.raw_sql_policy = deny: block all raw fragments.raw_sql_policy = allowlist: only allow fragments matchingraw_sql_allowlistpatterns.
Allowlist rules support plain substring rules and regex rules such as
'/^id\\s*=\\s*\\?$/i'.
Facade-Level Defaults#
For consistent policy across many connections, you can apply global defaults through the facade:
use Infocyph\DBLayer\DB;
DB::setSecurityDefaults([
'strict_identifiers' => true,
'queries_per_second' => 250,
]);
// Convenience profile (enables strict identifiers and require_tls=true).
DB::hardenProduction();
These values are applied as enforced facade policy across registered and future connections.
Rate Limiting and Confirmation#
Security utilities also include rate-limit checks and dangerous-operation confirmation gates:
Security::checkRateLimit('tenant:42');
Security::requireConfirmation('drop table users', confirmed: true);
Error and Log Hygiene#
Query failure exceptions expose statement type and SQL fingerprint, not full SQL text.
Logger redacts binding values by default.
Logger can mirror structured entries to any PSR-3 backend via
DB::setPsrLogger().
DB::enableLogger('/tmp/dblayer.log');
DB::logger()->setRedactBindings(true); // default
// DB::logger()->setRedactBindings(false); // opt out only for controlled local debugging
Warning
Security mode OFF disables automatic SQL validation. Use it only in
controlled internal scenarios, never as a default in shared environments.