1

I was trying to make a WordPress plugin work, when I found, after hours of debugging, trial, errors and praying ancient Greek gods, that the plugin did not work because it was impossible for the server to reach a particular file.

The website is hosted in a basic shared hosting environment, so the only thing that can be configured is a .htaccess file. This file is full of rules but I eventually found which one was causing the issue with the plugin:

RewriteRule ^wp-content/(?!themes/.*/core/css/custom\.css\.php$)(.*)\.php$ [R=404,L] 

When I commented out this rule, the plugin started working normally.

Now, I'm not a server or .htaccess expert but the person who coded this rule had some security treat in mind, so I would like to change it so that it simply allows my file to work.

The path of my file is:

wp-content/plugins/plugin-name/public/js/service-worker-loader.js.php 

Can you help me?

2
  • Did you resolve your other question (deleted)? If not then I would encourage you to re-ask on Webmasters SE. However, what you posted in that question looks OK. If that header is being set unconditionally then it suggests that something else is setting that header (or you are seeing a cached response). Commented May 19 at 11:52
  • Aside: If you are on Apache then it's very unlikely you are on Apache 2.2 (so far more likely to be on Apache 2.4). However, you could also be on a LiteSpeed server (behaves somewhere inbetween Apache 2.2 and 2.4). If on Apache 2.2 and you used an <If> expression then it would break your server with a 500 error. However, LiteSpeed tends to simply "ignore" anything it does not understand (no frontend error, except in the logs) - which actually makes debugging somewhat harder. Commented May 19 at 11:54

1 Answer 1

2
RewriteRule ^wp-content/(?!themes/.*/core/css/custom\.css\.php$)(.*)\.php$ [R=404,L] 

Aside: As written, this rule/directive is not correct. It is "missing" a second argument. (The third/flags argument will be treated as the second argument and result in requests that match this pattern being erroneously rewritten to the literal "URL" [R=404,L] - which is obviously not a valid URL and will likely result in a 404 in a very roundabout way... by WordPress, not Apache.)

I would expect the above rule to have a single hyphen (ie. -) as the second argument. For example:

RewriteRule ^wp-content/(?!themes/.*/core/css/custom\.css\.php$)(.*)\.php$ - [R=404] 

The L flag is not required here.

(That might seem subtle to the casual reader, but it is a glaring error/typo.)

HOWEVER, you do not need to modify that rule to resolve your issue. (Without knowing more about this, I would avoid editing this rule in case it was a WP plugin, rather than a "person", that wrote it. Although the fact that it is currently "wrong" as written still remains.) Instead, you can just add an additional rule at the very top of the .htaccess file to make an exception for the file in question. For example:

# Prevent further processing when file is requested RewriteRule ^wp-content/plugins/plugin-name/public/js/service-worker-loader\.js\.php$ - [END] 

This assumes Apache 2.4. (If you are on Apache 2.2 then use the L flag instead of END.)

This rule prevents any other mod_rewrite directives in the remainder of the .htaccess file being processed when that file is requested.


UPDATE:

Would it be possible to place a rule in another htaccess placed in the same directory of the file we're trying to grant access to? Or the higher htaccess takes precedence?

Yes, you can do that. Create another .htaccess in the subdirectory and simply disable the rewrite engine. For example:

# /subdirectory/.htaccess RewriteEngine Off 

Since mod_rewrite directives are not inherited by default, this effectively overrides the mod_rewrite directives in the parent (directory) config. The mod_rewrite directives in the parent are not processed so the request is not blocked.

(Each Apache module is processed differently. Directives from other modules, such as mod_expires, would still be processed in the parent/root config.)

8
  • A real person wrote that line! :-) Would it be possible to place a rule in another htaccess placed in the same directory of the file we're trying to grant access to? Or the higher htaccess takes precedence? Commented Aug 2, 2023 at 4:30
  • Unfortunately, your solution didn't work (I tried NEW and L, because there's no way to know my Apache version, phpinfo only mentions Apache without printing the version and PHP apache_get_version returns false) Commented Aug 2, 2023 at 5:59
  • 1
    @LifeafterGuest Yes, you can add another .htaccess file in the subdirectory instead if you wish. I've updated my answer. Commented Aug 2, 2023 at 8:59
  • 1
    @LifeafterGuest "no way to know my Apache version" - unfortunately some shared hosts do restrict this (although you should be able to get more info in your hosting control panel?), but doing so does not provide any additional security, it's just annoying. If you are on Apache then you are likely using Apache 2.4. However, an increasing number of shared hosts use LiteSpeed these days, which is a bit of a hybrid. If you had used NEW (instead of END) and didn't get a server error then you are likely using LiteSpeed. Commented Aug 2, 2023 at 9:00
  • 1
    @LifeafterGuest Yes, that will stop any other rewrites for requests to that subdirectory. If you are putting this in the /wp-content/plugins/plugin-name/public/js/.htaccess file then I would have thought that is desirable. Do you have any requests for files in that directory that should be handled by mod_rewrite (seems unlikely)? I would think the public/js subdirectory should only contain static assets? A <Files> container will not help here. You might be able to use an <If> expression to target specific URLs, but that's getting messy IMO (with additional complexity on LiteSpeed). Commented Aug 3, 2023 at 0:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.