Security Safeguards
Introduction
Security is a core design pillar of the Lacelium framework. Lacelium includes built-in defenses against the most common web application vulnerabilities, including Cross-Site Request Forgery (CSRF), Cross-Site Scripting (XSS), SQL Injection, session hijacking, and unvalidated file execution.
CSRF Protection
Cross-site request forgeries are a type of malicious exploit whereby unauthorized commands are performed on behalf of an authenticated user. Lacelium automatically generates a CSRF "token" for each active user session managed by the application.
CSRF in Forms
Anytime you define an HTML form that submits via POST, PUT, PATCH, or DELETE, you must include a hidden CSRF token field in the form so that the CSRF protection middleware can validate the request. You can use the Twig csrf_field() helper:
<form method="POST" action="/profile/update">
{{ csrf_field() }}
<input type="text" name="name" value="{{ user.name }}">
<button type="submit">Save</button>
</form>
CSRF in AJAX & Fetch
For JavaScript single-page apps or Fetch API calls, Lacelium also verifies the X-CSRF-TOKEN request header. You can extract the token from the <meta name="csrf-token"> tag:
fetch('/api/tasks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({ title: 'New Task' })
});
Cross-Site Scripting (XSS) Protection
All content rendered through the Twig templating engine is escaped by default using contextual HTML escaping. Double curly braces {{ user.name }} automatically convert characters like <, >, &, and " into their safe HTML entity representations.
If you intentionally need to render trusted HTML, you must explicitly use the raw filter:
<!-- Automatically escaped -->
<p></p>
<!-- Trusted HTML only -->
<div></div>
SQL Injection Safeguards
Lacelium uses PHP Data Objects (PDO) with prepared statements and parameter binding for all database interactions. Whether using the Eloquent ORM or the fluent Query Builder, user inputs are never concatenated directly into raw SQL strings:
// Safe: Parameter binding is handled automatically
$users = \App\Models\User::where('email', $request->get('email'))->get();
// Safe: Raw queries with explicit parameter binding
$results = db()->select('SELECT * FROM users WHERE active = ? AND role = ?', [1, 'admin']);
Password Hashing
Lacelium provides secure password hashing via PHP's native password_hash implementation, utilizing the memory-hard Argon2id algorithm by default (with automatic fallback to Bcrypt on older servers):
// Hashing a password
$hashed = password_hash($plainPassword, PASSWORD_ARGON2ID);
// Verifying a password during login
if (password_verify($inputPassword, $user->password)) {
// Password is valid
}
// Checking if rehashing is required due to upgraded work factors
if (password_needs_rehash($user->password, PASSWORD_ARGON2ID)) {
$user->password = password_hash($inputPassword, PASSWORD_ARGON2ID);
$user->save();
}
File Upload Validation
Uploaded files are one of the most dangerous attack vectors. Lacelium's fileUpload() helper inspects the underlying binary MIME signature via PHP's finfo extension rather than trusting user-provided client extensions:
// Rejects spoofed .php files masquerading as .jpg
$savedPath = fileUpload($file, 'uploads/avatars', [
'allowed' => ['image/jpeg', 'image/png', 'image/webp'],
'max_size' => 5 * 1024 * 1024,
]);
Session Security
Lacelium configures secure session defaults in config/session.php:
cookie_httponly = true: Prevents client-side scripts from reading session cookies.cookie_secure = true: Ensures cookies are only transmitted over HTTPS connections in production.cookie_samesite = 'lax': Protects against cross-site request attacks.
Next Steps
- Explore database persistence in Database Manager.
- Build complex queries with the Query Builder.
- Read the Deployment Guide for production security checklists.