Hm. Apache RewriteRule stopped working?

When your RewriteRule stops working, perhaps it is time to consider alternative solutions.


By. Jacob

Edited: 2023-08-09 00:02

At one point I thought I had found an easy way to limit access to certain web root directories on the server level using mod_rewrite with Apache. The problem usually is that once you throw a 404 on specific pages, users will be presented with the Apache's default 404 page instead of the one from your CMS. For some time I thought the following was working to show the intended CMS 404 message:

RewriteRule ^res/ / [L]
RewriteRule ^data/ / [L]

While investigating another unrelated issue I discovered that it was no longer working, if ever, and to my horror users could now request files located inside certain unintended subdirectories I thought I had 404'ed out. This was a surprise because I had already tested this at length in the past. Maybe I have later changed the code and forgotten about it, or something changed with a server update. Either way, one thing was sure: it was not working.

I remember another variation of this trick that looked something like this:

RewriteRule ^res/ /?404 [L]
RewriteRule ^data/ /?404 [L]

This also did not work when I tried it. The idea was to rewrite the directories you want to block to a non-existent CMS-served-URL, which would then show the CMS' 404 message.

Fundamentally, however, I was thinking of using the wrong tool for the job; I was already directing all traffic through index.php, even static files. Some advantages to doing this:

Apache's configuration tend to call for weird syntax compared with using a regular expression in your PHP router to match URLs – the solution is therefor simple: move this logic to the Router code!

The router should support supplying a list of directories to exclude, and then, whenever something within that directory is requested, show a 404 message to the user. This list should be easily modifiable from a central location like a configuration file and/or certain patterns hard-coded inside the router.

Another solution is to move your CMS files outside of the public folder. Shopware does that by having a folder like /var/www/shopware/public/ while placing system files in /var/www/shopware/ – which is more practical? None. But you probably want your traffic through index.php regardless – at least for files you intend to control access to.

This does not mean you should not configure things on the server-level. It is still the fastest way to handle static file requests – but if you can, don't be afraid to do both, because one does not have to exclude the other.

Tell us what you think: