Files firewall - Recipe for K3

Hi Kirby team,

I saw that there is a Kirby V2 asset firewall tutorial to protect files from being accessed directly:

K2 Asset Firewall Recipe

When will you release a recipe for V3? I ask this because I want to create an internal area just for logged in users. Of course the internal files shouldn’t be accessible from outside. However, some things changed from V2 to V3 and a new recipe would be quite helpful.

Thanks for your answer.


1 Like

I created an issue for it in our website repo:

However, I cannot promise any ETA.

1 Like

Any news on this? Or someone who could give me some hints?

I might be off but I think this is sort-of built-in, considering following changes:

  1. Move your content-folder off the public accessible webroot folder of your webserver. Change Kirby’s index.php file for this, e.g.:
include '../kirby/bootstrap.php';
$kirby = new Kirby([
    'roots' => [
        'index'   => __DIR__,
        'content' => __DIR__ . '/../content',
        'site'    => __DIR__ . '/../site',
echo $kirby->render();
  1. As long as you keep your internal area in draft-status, I think nothing should be accessible?

@bvdputte That won’t work because assets are moved to the media folder and will still be accessible there, at least if you know the URL. It’s not that easy to guess, but that would be security through obscurity more than anything else.

I agree it’s not 100% safe, but as an “in-between hack” it’s not bad imho: you’ld have to guess for a filename + its hash. Good luck with that :sweat_smile:.

But I get your point-of-view, as long as you can’t guarantee no-file-access-to-unauthenticated-users you have to state this clearly.

Thank you for your suggestions. It seems to be a workaround, but I’d rather implement a safer option because as you mentioned it is still not 100% safe (nothing is, but you get the point). However, I think I have no other choice for now. Unfortunately, I still haven’t managed to implement an asset firewall in V3 :frowning:

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]

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.

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:

IMO, it would be better to have a solution that works with the content folder inside the document root, because on shared hosting you can’t move the folder outside the web root.

But it would mean that we would have to block access to the media and the content folders conditionally.

1 Like

Maybe it is possible to extend a controller or route or something of this plugin to catch also the coresponding parts inside media-folder? (i’m not a coder :smile: )

@Kirby team:

I have a question about the “.htaccess” file from the Kirby Starterkit:
why does the “content” line of this file only prevent access to the three text formats?

As I understand it, all access to the “/content” path of the web server is redirected for visitors of the website by Kirby to the “/media” folder.
If my observation is correct, this would be an entry into a “files firewall” with a standard Kirby configuration.


I have seen you have changed the .htaccess file in the Starterkit repro.

May I ask, if there is a difference to the Plainkit repro, not to the same?

And may be in the Demokit repro, may be after some more tests?

As you can see in, it was planned from the beginning to make the same changes in the Plainkit – which I have already committed to the Plainkit repository even before reading your comment in the forum.

The Demokit is used for our public Kirby demo at, which doesn’t benefit from the changes.

Many thanks for your very helpful explanations.