Disallow Mautic access remotely but allow unsubscribe link

Your software
My Mautic version is: v3.3.5
My PHP version is: 7.3.33
My Database type and version is: MariaDB 10.5.15
My Webserver is: Apache v2.4.6

My problem is:

Very simple question. Does anyone have a quick .htaccess snippet or another method to disallow remote access to Mautic, but still allow the campaign ‘Unsubscribe’ links to work? (Ie. to “http://mymautic.example.com/email/unsubscribe/xxxxxxxxxx”)

I imagine it’s very simple, but I’m not finding an example and quite honestly Apache directives make my head hurt. :slight_smile:

Essentially I’m looking for src: 192.168.0.0/16 to be allowed to the dashboard, anything else only allow access to the email unsubscribe link.

Thank you!

Hello @dspraker,

If I understand correctly you want to :

Is this correct?

Pierre

Exactly. The /email/unsubscribe is sent out via the campaign emails, and that is the only type of external access I would like.

I am not an expert at apache but I think what you are looking for is something like - this is not tested:

  # Except those allowed below.
    <If "%{REQUEST_URI} =~ m#^/(index|index_dev|upgrade/upgrade)\.php#">
        Order allow,deny
        Deny from all
        Allow from [your IP]
    </If>

    <If "%{REQUEST_URI} =~ ^/email/unsubscribe/(.+)$">
        Order allow,deny
        Allow from all
    </If>

Well, it looks valid, but you’re right… not working. I get:

[Fri Apr 01 16:52:10.036466 2022] [core:alert] [pid 9930] [client 192.168.xx.xx:50518] /var/www/html/.htaccess: Cannot parse condition clause: syntax error, unexpected T_ERROR, expecting T_REGEX or T_REGEX_I: Parse error near '^', referer: http://192.168.xx.xx/

Because the .htaccess is just a bunch of rewrite modules, I just put them into the top. Look valid?

# Use the front controller as index file. It serves as a fallback solution when
# every other rewrite/redirect fails (e.g. in an aliased environment without
# mod_rewrite). Additionally, this reduces the matching process for the
# start page (path "/") because otherwise Apache will apply the rewriting rules
# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl).
#DirectoryIndex index.php

    <If "%{REQUEST_URI} =~ m#^/(index|index_dev|upgrade/upgrade)\.php#">
        Order allow,deny
        Deny from all
        Allow from 192.168.0.0/16
    </If>

    <If "%{REQUEST_URI} =~ ^/email/unsubscribe/(.+)$">
        Order allow,deny
        Allow from all
    </If>

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Set Authorization header for OAuth1a for when php is running under fcgi
    RewriteCond %{HTTP:Authorization} .+
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Actually if you investigate the original mautic .htaccess file you will see that the first if block is already there:

just see what the body has originally and make sure its the same as what I have posted.

Now you also have to add the second if block after that, but based on the error message you posted and the apache docs it looks like I did not enclose the regex, so try adding this block after the edited one:

<If "%{REQUEST_URI} =~ m#^/email/unsubscribe/(.+)$#">
        Order allow,deny
        Allow from all
    </If>

If this still does not work, let me know, I will try to test it myself (although I am not using apache).

Still not working, but differently. Apparently the newer versions of Apache have changed the directives:

    <If "%{REQUEST_URI} =~ m#^/(index|index_dev|upgrade/upgrade)\.php#">
        Require ip 192.168.0.0/16
    </If>

    <If "%{REQUEST_URI} =~ m#^/email/unsubscribe/(.+)$#">
        Require all granted
    </If>

This works fine for blocking access to the dashboard (Thanks for the info on the regexes!), but it’s also blocking access to the unsubscribe link.

http:/xxxxxxx.xxxxxxxx.xxx/email/unsubscribe/621fd775708fa422323133 now gives:

Forbidden

You don’t have permission to access /index.php on this server.

[Mon Apr 04 10:14:50.603602 2022] [authz_core:error] [pid 27955] [client 184.xxx.xxx.xxx:40802] AH01630: client denied by server configuration: /var/www/html/index.php

So apparently it’s redirecting the unsubscribe link through the primary index.php, but that’s being blocked by the other block

I have tried this yesterday, this time via RewriteEngine and still was not successful, sorry, but I think somwhere in direction I have shown must be the solution. Will post here if I find the solution.

Thanks. It seems like an obvious thing that I think most people would want by default… allow people to unsubscribe, but not allow them to try to login/hack the Admin panel.

If you can think of anything please do let me know, and thank you again for looking at it

Yeah in general you do not want to block all the access since tracking will also not work. There are other ways to strengthen the defense.

Like:

  • fail2ban
  • block access to sites on app level (its not the right way to do this - the apache is)
  • proper server monitoring
  • etc.