Issues with CORS when trying to configure Mautic 3 and NGinx

Your software
My PHP version is : 7.2.32
My MySQL/MariaDB version is (delete as applicable): MySQL 8
My Webserver is: NGinx

Updating/Installing Errors
I am (delete as applicable): Installing
Upgrading/installing via (delete as applicable) : Web

These errors are showing in the installer :

N/A

These errors are showing in the Mautic log :

N/A

These errors are showing in the upgrade_log.txt file (located in the root of your Mautic instance when an upgrade has been attempted - ensure you remove or redact any sensitive data such as domain names in the file path) :

N/A

Your problem
My problem is :

When trying to implement CORS, I get the following error in the Javascript console of the webpage that calls the tracking script:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://<MY MAUTIC SERVER>/mtc/event. (Reason: Multiple CORS header ā€˜Access-Control-Allow-Originā€™ not allowed).

In my NGinx config I have the following:

        add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Origin' $http_origin;
        add_header 'Access-Control-Allow-Credentials' "true";

In Mautic, Iā€™ve got ā€œRestrict Domainsā€ set to YES, and Iā€™ve listed all of the calling domains in ā€œValid Domainsā€ text field, however no matter what I change the NGINX headers or Mautic Settings to, I get the same errors.

The only thing Iā€™ve not done is change the tracking code after each change to the server - does Mautic recreate the tracking code based on the value of ā€œRestricted Domainsā€?

OK, Iā€™ve switched the setting from add_header 'Access-Control-Allow-Origin' $http_origin; to add_header 'Access-Control-Allow-Origin' $http_referrer; and this has changed the message in the Javascript Console to

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://<MY MAUTIC URI>/mtc/event. (Reason: expected ā€˜trueā€™ in CORS header ā€˜Access-Control-Allow-Credentialsā€™).

however as you can see from the config in my original post, that value is set as requested.

Did you ever resolve this issue completely?

Hi,

This hasnā€™t been solved yet, no.

Thereā€™s an issue on Github for it: https://github.com/mautic/mautic/issues/9019

This is an excellent writeup @lexgabrees. Iā€™ve never seen the CORS items documented before elsewhere. Is this required for CORS to work at all? Also, with this set in nginx, what settings are required in the CORS settings in Mautic Configuration? Should that be set to ā€œNoā€ for limiting domains or ā€œYesā€ with any appropriate domains included? We have a base domain, a separate sub domain for landing pages, etc.

Hi ericc ā€¦

These settings are indeed necessary for CORS to work at all on this setup. Without these settings, CORS will be an ā€˜emptyā€™ feature (not working).

If you have placed the settings in the config file, then you can set the CORS feature to ON and enter the domain names. If the CORS feature is OFF, then, well, itsā€™s OFF.

You can see the CORS restriction in the developer tools when reloading the page.

Lex

@lexgabrees thatā€™s fantastic, thanks, especially as Iā€™m working in DigitalOcean already even if my deploy is a slightly more complicated setup!

Unfortunately, since upgrading to 3.0.2, Iā€™ve hit an issue whereby the server just constantly redirects me to / so Iā€™m trying to fix that before coming back to thisā€¦ :frowning:

An update - Iā€™ve been working through this today and it looks like my install of 3.0.2 was dodgy for some reason.

Iā€™ve re-installed and thatā€™s made the blank page/redirect failure go away, however Iā€™m still hitting the same issue with CORS.

@lexgabrees - Iā€™m wondering if this is because Iā€™m hosting Mautic behind a DO Loadbalancer - have you tried that particular configuration?

Iā€™m not using a Load balancer. Iā€™m using the direct set up thatā€™s described in my installation guide. Are you using Nginx as a load balancer + apache ? Or are you using only Nginx for everything ?

Also, what errors are you seeing in the developer tools ?

This has probably something to do with the location blocks in the Nginx config ā€¦

Nope, the configuration is as follows:

DigitalOcean LoadBalancer with LetsEncrypt TLS Certs -> NGinx
 -> PHP-FPM -> Mautic -> DigitalOcean Database As A Service

The error Iā€™m seeing in the developer tools is now:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://mautic.<MY DOMAIN>/mtc/event. (Reason: CORS header ā€˜Access-Control-Allow-Originā€™ missing).

and my NGinx config looks as follows:

server {
	listen      80;
	server_name mautic.<MY DOMAIN>;
	root         /var/www/;
	index       index.php;

        server_tokens off;
        # CORS settings start
        add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Origin' "$http_referrer";
        add_header 'Access-Control-Allow-Credentials' "true";
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        # CORS settings end
        add_header 'X-Frame-Options' '';

	client_max_body_size 64M;
 
        gzip on;
	gzip_disable "msie6";
        gzip_min_length 256;

	gzip_vary on;
	gzip_proxied any;
	gzip_comp_level 6;
	gzip_buffers 16 8k;
	gzip_http_version 1.1;
        gzip_types
            font/truetype
            font/opentype
            font/woff2
            text/plain
            text/css
            text/js
            text/xml
            text/javascript
            application/javascript
            application/x-javascript
            application/json
            application/xml
            application/rss+xml
            image/svg+xml;
       
            error_page 404 /index.php;


    # redirect index.php to root
    rewrite ^/index.php/(.*) /$1  permanent;

    #######################################
    ##  Start Mautic Specific config #####
    #######################################

    # redirect some entire folders
    rewrite ^/(vendor|translations|build)/.* /index.php break;

    location / {

		# First attempt to serve request as file, then
		# as directory, then fall back to index.html
        # one option: try_files $uri $uri/ /index.php$is_args$args;
        try_files $uri /index.php$is_args$args;
 		# Uncomment to enable naxsi on this location
		# include /etc/nginx/naxsi.rules
	}

    # Deny everything else in /app folder except Assets folder in bundles
    location ~ /app/bundles/.*/Assets/ {
        allow all;
        access_log off;
    }
    location ~ /app/ { deny all; }

    # Deny everything else in /addons or /plugins folder except Assets folder in bundles
    location ~ /(addons|plugins)/.*/Assets/ {
        allow all;
        access_log off;
    }
    # location ~ /(addons|plugins)/ { deny all; }

    # Deny all php files in themes folder
    location ~* ^/themes/(.*)\.php {
        deny all;
    }

    # Don't log favicon
    location = /favicon.ico {
    	log_not_found off;
    	access_log off;
    }

    # Don't log robots
    location = /robots.txt  {
    	access_log off;
    	log_not_found off;
    }

    # Deny yml, twig, markdown, init file access
    location ~* /(.*)\.(?:markdown|md|twig|yaml|yml|ht|htaccess|ini)$ {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Deny all attempts to access hidden files/folders such as .htaccess, .htpasswd, .DS_Store (Mac), etc...
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Deny all grunt, composer files
    location ~* (Gruntfile|package|composer)\.(js|json)$ {
        deny all;
        access_log off;
        log_not_found off;
    }

    #######################################
    ##  End Mautic Specific config #####
    #######################################

        location ~*  \.(jpg|jpeg|png|ico|pdf)$ {
                expires 15d;
        }

	# Deny access to any files with a .php extension in the uploads directory
        location ~* /(?:uploads|files)/.*\.php$ {
                deny all;
        }

        # Solve email tracking pixel not found
        location ~ email/(.*).gif {
        try_files $uri /index.php?$args;
        }
        # Solve JS Loading 404 Error
        location ~ (.*).js {
        try_files $uri /index.php?$args;
        }


	location ~ \.php {
		include fastcgi.conf;
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		fastcgi_pass unix:/var/run/php-fpm/www.sock;
	}
	location ~ /\.ht {
		deny all;
	}
}

Okay ā€¦ so you are using the DigitalOcean load balancer and serving Mautic with purely nginx? Could you paste a link of the optin form thatā€™s having the issues ?

Sure, itā€™s a test site on Netlify.

Iā€™ve added the domain to the CORS domain list in Mautic, along with our primary domains, and Iā€™ve set the header in Nginx to return the value of $http_referrerā€¦

and as Iā€™m typing that Iā€™ve realised that the referrer is probably the load balancer, not the original site, let me make a quick changeā€¦ :smiley:

Looks to me (as I look at the dev tools and the errors there) that the load balancer is blocked by CORS policy ā€¦ So, CORS is doing something ā€¦ You might want to see what happens with CORS off ā€¦ First make sure that CORS is properly working and isolate the issue from there ā€¦

OK, it wasnā€™t what I thought. :frowning:

If I set the Access-Control-Allow-Origin to $http_x_forwarded_for then it errors saying that my IP address is not in the list of allowed hosts, whereas if I set it to $http_origin then it says that the header was not returned at all :frowning:

ok, so turn it off in Mautic, but leave the Nginx config, or turn it off in both places?

ok, so disabling from within Mautic but keeping my existing header setup gives me:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://mautic.tooling.mockingbirdconsulting.co.uk/mtc/event. (Reason: expected ā€˜trueā€™ in CORS header ā€˜Access-Control-Allow-Credentialsā€™).

Switching to your header setup, but continuing to keep Mautic CORS disabled works, and youā€™re quite right, this did put me on to the right path.

If you use your ā€œsimpleā€ CORS headers, and make sure that you use https:// infront of all of the domains in the ā€œValid Domainsā€ box instead of just the FQDN, then it works.

So, in essence, donā€™t over-complicate the CORS Headers, and make sure that you use the URI, NOT the FQDN (which is what it actually asks for, even if the example shows http://foo.example.com!) in the ā€œValid Domainsā€ box, and it should work!

1 Like

I think it must be working for me without those specific settings. Iā€™m using the Mautic tracking js code in a Google Tag instead of adding it to the site. I have CORS enabled with my domains in there. I am seeing page hits successfully across the main domain and landing pages. No errors in developer tools.

My mautic installation is also a subdomain URL of my main domain, so I assume thatā€™s the reason itā€™s working without this specific fix.

Hi there, I have seen other threads discussing similar. It sounds like you have it running, but I believe by default Mautic disables tracking from ā€œinternal networksā€. Could be something related to this as the load balancer is viewed as ā€œlocalā€ traffic? I think the solution was to disable that feature in the local.php file.

As Iā€™m typing this, sounds like this would not create a CORS error in the browser, but could account for not seeing a CORS error, but still not seeing tracking.

The tracking is working fine now that CORS is working, it was the tracker script being blocked that was the issue, but thanks for the thoughts, something to keep in mind in future!