HTTP Security Headers

HTTP security headers play a critical role in protecting Flarum installations against common web vulnerabilities. While some headers are best implemented at the server level, Flarum provides mechanisms to enforce key protections through its configuration.

The X-Frame-Options header prevents clickjacking attacks by controlling whether your forum can be embedded in frames. Flarum allows configuring this through an array in config.php, specifying allowed domains:

return [
  'x-frame-options' => ['SAMEORIGIN'],
];

For XSS protection, Flarum enables the X-XSS-Protection header by default, which activates browser-based XSS filtering. This should remain enabled unless you have specific requirements to disable it.

Content Type Options prevents MIME type sniffing, forcing browsers to honor declared content types. Flarum implements this through:

return [
  'x-content-type-options' => 'nosniff',
];

Session Security

Flarum's session management incorporates several security features that require proper configuration. The SameSite cookie attribute controls whether cookies are sent with cross-site requests, protecting against CSRF attacks.

By default, Flarum sets SameSite to Lax, which balances security and usability. This prevents cookies from being sent with cross-site POST requests while allowing GET requests from external links. In high-security environments, consider Strict mode:

return [
  'session' => [
    'same_site' => 'Strict',
  ],
];

Session expiration is managed through Flarum's configuration file, with default settings providing adequate protection. However, sensitive applications should reduce session lifetimes:

return [
  'session' => [
    'lifetime' => 7200, // 2 hours in seconds
  ],
];

GDPR Export Protection

Flarum's GDPR export functionality handles sensitive user data, requiring robust security measures. Recent updates have significantly improved export protection through several mechanisms:

Exports now enforce active expiration, ensuring files cannot be accessed after their destruction time, even if the cleanup cron hasn't run. This prevents timing window vulnerabilities where expired tokens remained valid.

Single-use tokens ensure each export can only be downloaded once. After access, the system records download details including timestamp, IP address, and user agent for auditing purposes.

The export cleanup process has been enhanced to maintain an audit trail while securely removing sensitive data. Instead of deleting entire rows, the system removes the ZIP file and nulls the file column while preserving audit information.

These changes, implemented in Flarum 2.x, provide defense in depth for GDPR exports while maintaining usability:

return [
  'gdpr' => [
    'export_lifetime' => 86400, // 24 hours in seconds
    'audit_retention' => 2592000, // 30 days in seconds
  ],
];

Configuration Best Practices

Proper Flarum configuration extends beyond individual security features. Regular reviews of security settings and adherence to best practices are essential:

Maintain strict file permissions, ensuring configuration files are not world-readable. Flarum's configuration typically resides in config.php, which should have permissions set to 600.

Regularly update Flarum and its extensions to incorporate security fixes. The update process should be tested in a staging environment before deployment.

Implement server-level security measures including HTTPS enforcement and proper HTTP headers. While Flarum handles some headers internally, others like HSTS are best implemented at the server level.

Monitor access logs for suspicious activity, particularly around administrative functions and GDPR exports. Flarum's built-in logging provides valuable security insights.