Security

CSRF protection, sessions, password reset tokens, and logging. Secure by default.

CSRF Protection

Enabled by default if 'csrf_token' => true in config. A unique token is generated per session.

Add to forms:

<input type="hidden" name="token" value="<?= TokenManager::csrf() ?>">

Verify in controller:

$tm = new TokenManager();
$result = $tm->verify($_POST['token']);

if ($result['status'] === 'success') {
    // Token valid, process form
} else {
    // Invalid or expired
}

Sessions

Session is auto-started in app/start.php. Use the PREFIX constant to avoid conflicts:

$_SESSION[PREFIX . 'user_id'] = $user->id;
$userId = $_SESSION[PREFIX . 'user_id'] ?? null;

Sessions are secure: HTTPOnly, SameSite=Lax by default. Configure in app/config.php.

Password Reset

User module includes secure token-based reset with expiry:

  1. User requests reset → token generated, stored with expiry
  2. Token emailed via PHPMailer
  3. User clicks link → token validated → password updated
  4. Token invalidated

Tokens expire after 1 hour. See strata/user module.

Logging

Security/auth events logged to storage/logs/ via Logger class:

use Strata\Logger;

Logger::info('User login', ['user_id' => $userId, 'ip' => $ip]);
Logger::warning('Failed login attempt', ['email' => $email]);
Logger::error('CSRF token mismatch', ['token' => $token]);

Logs are rotated daily. Path configurable in app/config.php.

Input Validation

Always validate and sanitize. Never trust user input.

$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if (!$email) {
    throw new ValidationException('Invalid email');
}

// Parameterized queries via DB class
DB::query('SELECT * FROM users WHERE email = ?', [$email]);

No eval, exec, system except admin modules. Validation system checks for this.