Files firewall - Recipe for K3

I think I found a way build a files firewall. Here’s what I’ve done …

1. Content folder

Use the public folder setup to move all files of the content folder outside of your DocumentRoot.

2. .htaccess

Add the following .htaccess file to the media folder. It will redirect all file requests back to index.php which can then be handled by Kirby.

<IfModule mod_rewrite.c>
  RewriteCond %{REQUEST_URI} ^\/media\/pages
  RewriteRule ^(.*) /index.php [L]
</IfModule>

3. Hooks

Use your config file or create a custom plugin to make use of the Kirby hook system. In this case I implemented a route:before hook like this.

<?php
return [
    'hooks' => [
        'route:before' => function ($route, $path, $method) {
            if (Str::startsWith($path, 'media/pages')) {

                // e.g. allow file access for all panel users
                if (kirby()->user() && kirby()->user()->role()->permissions()->for('access', 'panel')) {
                  return $route;
                }

                // e.g allow file access based on a page field called myCustomToggleField
                $arguments = $route->arguments();
                $filepath  = $arguments[0] ?? false;

                if ($filepath && $filePage = page($filepath)) {
                  if ($filePage->myCustomToggleField()->bool()) {
                    return $route;
                  }
                }

                // deny access in any other case
                // Header::forbidden() does not work here?!
                die('Access denied');
            }
        }
    ]
]

My tests had been successful so far but …

Did I miss something? Any feedback is highly appreciated!

Thanks in advance :blush: