⬡ Lacelium
⌘K
Version 2.x ▾

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