Configure GRAV Properly for Security

Security is a fundamental concern when managing any website, especially when working with a content management system like Grav CMS. Although Grav is inherently more secure than other platforms due to its database-less architecture, it is always advisable to take additional measures to protect your site. In this article, we guide you step by step to configure Grav properly and minimize risks.

This guide is based on my own learnings during the development of VeleroAzul and the valuable recommendations provided by my AI assistant.


1. Keep Your Site Updated

Updates include security patches and important improvements. Make sure to keep both Grav and all its plugins updated:

  • From the admin panel: Tools > Check for Updates.
  • From the command line:
    bin/gpm self-upgrade
    bin/gpm install grav

2. Secure Access to the Admin Panel

The admin panel (/admin) is a critical entry point. Protect this access by following these steps:

a) Use Strong Passwords

Change the default password to a secure one (at least 12 characters with letters, numbers, and symbols). Enable two-factor authentication (2FA) if possible.

b) Rename the /admin Route

Changing the admin route makes unauthorized access attempts more difficult. Edit user/config/system.yaml:

admin:
    route: /your-new-secret-route

c) Restrict Access by IP

If you navigate from fixed IPs, restrict access to the admin panel to these addresses only. Create an .htaccess file in /admin (for Apache):

Order deny,allow
Deny from all
Allow from 123.456.789.012  # Replace with your IP address

For Nginx, configure in your server config:

location /your-new-secret-route {
    allow 123.456.789.012;  # Replace with your IP address
    deny all;
}

3. Disable Unnecessary Features

Remove or disable plugins and features you don't use. Each additional component can be a potential attack vector. Go to Plugins in the admin panel and deactivate what you don't need.


4. Protect Sensitive Files

Block direct access to sensitive directories using .htaccess. Here’s what you’ve already done and some additional suggestions:

a) /user Directory

Protect this directory with a custom .htaccess:

<Files "*">
    Order deny,allow
    Deny from all
</Files>

<FilesMatch "\.(yaml|md|txt|json|woff|woff2|ttf|eot|svg|png|jpg|jpeg|gif|css|js)$">
    Allow from all
</FilesMatch>

b) /cache and /logs Directories

Add a basic .htaccess to these directories:

Deny from all

c) Clear Cache Regularly

Run this command periodically:

bin/grav clear-cache

5. Configure HTTPS

Enable HTTPS to encrypt all communication between the client and server. Use Let's Encrypt for a free SSL certificate. In your main .htaccess file, redirect all traffic to HTTPS:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

6. Add Basic HTTP Authentication for /admin

Add an extra layer of security with basic HTTP authentication. This requires creating an .htpasswd file with secure credentials.

For Apache:

Create an .htaccess file in /admin:

AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/your/file/.htpasswd
Require valid-user

Generate the .htpasswd file:

htpasswd -c /path/to/your/file/.htpasswd your-username

For Nginx:

Configure in your server config:

location /your-new-secret-route {
    auth_basic "Restricted Area";
    auth_basic_user_file /path/to/your/file/.htpasswd;
}

7. Monitor Logs

Regularly review system logs to detect suspicious activities:

  • Grav logs are located in /logs.
  • Web server logs (Apache or Nginx) can also provide clues about unauthorized access attempts.

8. Disable Debug Mode

Debug mode exposes sensitive error information. Disable it in production:

debug:
    enabled: false

9. Restrict Third-Party Plugins

Install only trusted plugins and keep them updated. Avoid unnecessary plugins.


10. Set Up a Firewall

A firewall adds an extra layer of protection against malicious attacks. Popular options include:

  • Cloudflare: Offers free DDoS protection and firewalls.
  • Server Firewall: Configure specific rules to block suspicious traffic.

11. Make Regular Backups

Backups are crucial for recovering from failures or attacks. Use the official Backup plugin or automate backups with scripts like rsync.


12. Configure Matomo Analytics Without Cookies

If you use Matomo, ensure it is configured without cookies to comply with GDPR. Verify that it does not track personal data.


13. Protect Against CSRF Attacks

Enable CSRF protection in user/config/security.yaml:

csrf:
    enabled: true

14. Clean Temporary Files

Remove temporary files that may accumulate sensitive information:

bin/grav clear-temp

15. Set Proper Permissions

Set appropriate file and folder permissions to prevent unauthorized access:

find /path/to/grav -type d -exec chmod 755 {} \;
find /path/to/grav -type f -exec chmod 644 {} \;
chmod -R 775 /path/to/grav/cache
chmod -R 775 /path/to/grav/logs

16. Add a robots.txt File

Prevent malicious bots from indexing sensitive parts of your site. Example:

User-agent: *
Disallow: /admin/
Disallow: /cache/
Disallow: /logs/
Disallow: /backup/
Disallow: /user/
Allow: /user/pages/
Allow: /user/themes/
Allow: /user/images/
Allow: *.css$
Allow: *.js$

17. Consider Using a CDN (Optional)

A CDN like Cloudflare improves performance and provides additional security layers, such as DDoS protection.


Conclusion

Following these steps will ensure your Grav site is well-protected against common threats. Remember, security is never complete: regularly check updates, monitor logs, and adjust configurations as needed.

This guide is based on my own learnings during the development of VeleroAzul and the valuable recommendations provided by my AI assistant. I hope it proves useful to you and other Grav users looking to enhance their site's security.