XMLHTTPRequest cannot load URL_HERE due to access control checks

Since a few weeks I’ve been noticing an issue when saving new or editing posts and stuff in CP.
I’m not sure what’s going wrong, or what causes it. But it seems to have something to do with Cookie (or their policies) or CORS. I don’t really understand the problem yet and my hosting provider is a twat in explaining anything blaming everything but themselves - Not very helpful in even understanding what’s going wrong…

Expected behavior

When I click ‘Save as Draft’ or ‘Publish’ that the posts savespublishes

Current behavior

It starts loading/saving, stalls and eventually times out on a white screen.
If you look in console it gives a non descript error:

XMLHTTPRequest cannot load URL_HERE due to access control checks

Screenshot: https://disk.stor.fit/index.php/s/7tcJ4GmzeTQ2zC7

Possible solution

No idea - According to my hosting provider something with cookies. THey put the following in .htaccess:

Header always edit Set-Cookie (.*) “$1;HttpOnly;Secure;samesite=lax”

But that didn’t help

Steps to reproduce

As described, save a page/post/product (in CC) and eventually it starts stalling and giving that error.
Sometimes this happens after a few times saving (say 3-5) other times after 15+ times.

Akin to a stupid firewall blocking repeated requests. Though I’m assured it’s not a firewall.

I’ve tried and seen the issue in Safari 15.x and Firefox 102 (macOS).

I have several sites on CP and most work fine.
So far I’ve only noticed this only on ONE of the sites, but that’s also the one I edit and post on the most currently, so perhaps all of them have it but I don’t do enough to it to cause the issue.

It’s super frustrating though.
Anyone else has this problem? What do I do about it? Where is the issue? CP? Server? Browser?

This shouldn’t be an issue in ClassicPress. Especially if nothing has changed when this issue showed up. Sometimes a change to server configuration can cause unintended consequences.

Let’s try enabling CORS and see if that helps. Add the following to the top of your .htaccess file:

Header set Access-Control-Allow-Origin "*"

If that doesn’t work, also try this version:

Header add Access-Control-Allow-Origin "*"

See if that works. Let us know.

1 Like

I haven’t seen this before. But are you sure that everything on your site is set to https (and not http) and also that you are consistent about whether you have a www. or not at the beginning of your website URL?

You should have your host remove what they did, because that’s opening a security issue. What they could try instead is replacing it with this:
Access-Control-Allow-Headers: Origin

Will do, thanks for the quick reply!

Yes, I use the force https thing in wp-config.php and also have a forced redirect in .htaccess that works pretty good.
So that’s not the issue.

I’m not sure if it’s a new thing or that it always was happening but i just didn’t notice it before.
I rent this VPS and have done so for 2 years now. Several sites on it. And all seems well - Except for this issue.

I just looked at the .htaccess - The first line is already in there, has been since day one.
I have had this stuff in there for at least a year now.

At the very top, the recent changes/suggestions. But that seems redundant now.

See below:

## nkimh 06/24/22 addition, ticket #6432220
#Header always edit Set-Cookie (.*) "$1;HttpOnly;Secure;samesite=lax"
Header set Access-Control-Allow-Origin "*"

# Use UTF-8 encoding for anything served text/plain or text/html
AddDefaultCharset UTF-8
AddCharset UTF-8 .css .js

# Cache Control
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
Header set Connection keep-alive
Header set Access-Control-Allow-Origin "*"
Header unset Pragma
Header append Cache-Control "public"
<filesmatch "\.(ico|gif|swf|eot|woff|otf|ttf|svg)$">
	Header set Cache-Control "max-age=2592000, public"
</filesmatch>
<filesmatch "\.(jpg|jpeg|png)$">
	Header set Cache-Control "max-age=1209600, public"
</filesmatch>
<filesmatch "\.(css)$">
	Header set Cache-Control "max-age=31536000, private"
</filesmatch>
<filesmatch "\.(js)$">
	Header set Cache-Control "max-age=1209600, private"
</filesmatch>
<filesMatch "\.(x?html?|php)$">
	Header set Cache-Control "max-age=600, private, must-revalidate"
</filesMatch>

# Gzip compression
SetOutputFilter DEFLATE

# Force deflate for mangled headers
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding

# Don’t compress images and other uncompressible content
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|rar|zip|exe|flv|mov|wma|mp3|avi|swf|mp?g|mp4|webm|webp)$ no-gzip dont-vary

# Compress all output labeled with one of the following MIME-types
AddOutputFilterByType DEFLATE application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/html text/plain text/x-component text/xml
Header append Vary: Accept-Encoding

# Compress compressible fonts
AddOutputFilterByType DEFLATE font/ttf font/otf image/svg+xml

# Rewrite rules
RewriteEngine On
RewriteBase /

# FORCE SSL
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# Exclude from WordPress redirects
## Nothing

# Hack/backdoor Security
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]

# Block unused request methods
RewriteCond %{REQUEST_METHOD} ^(CONNECT|DEBUG|DELETE|MOVE|PUT|TRACE|TRACK) [NC]
RewriteRule .* - [F,L]

# Bruteforce Protection
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .*/(wp-comments-post|wp-login)\.php.*
RewriteCond %{HTTP_REFERER} !.*mototravel.net.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) - [R=403,L]

# Block WordPress xmlrpc.php requests
<Files xmlrpc.php>
 order deny,allow
 deny from all
</Files>

And then the ‘wordpress’ bit and a few redirects below it

Same issue with this added:

Header add Access-Control-Allow-Origin “*”

Of-course I commented out the other 2 lines.

Can you test the default .htaccess configuration, please? If the issue persists with default htaccess, we will at least eliminate any custom rules added to htaccess. So we can focus on other areas to troubleshoot.

The easiest way to do this. Rename current .htaccess file to htaccess.txt. Then create a new .htaccess and add the following:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Once saved. Test to see if issue is gone or not.

Hah yes!
I just tried this:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Then added your suggested line from before above it.
Both failed on the first save attempt.

Keep in mind that all that .htaccess stuff worked fine for months. I use a almost identical version of it on another site and don’t see this issue there (yet/or at all).

In my ticket to the hosting company I at first suspected the firewall - As that’s a thing they messed with a few months ago. Partly because it works on my other site (on a different vps) but also because both sites aside from a bunch of plugins are set up the same, same htaccess, same php/modules/whatever as far as i can control that.

Have you checked your Apache error log to see if admin-ajax.php requests show any server-side errors?

Also, can you test if admin-ajax.php requests are being blocked in the frontend?

Nothing in the error_log :upside_down_face:

I’m not sure how to test admin-ajax.php in the front-end I’m not overly familiar with it - I don’t think my site/theme does much admin-ajax-y there.
There are a few references to it in the source, for adding things to the shopping cart for example (Classic commerce), but that works fine as far as I can tell.

Check it out - The site is fairly straightforward without much gimmicks really: https://mototravel.net

I’m still not sure what the problem is or what to do about it.
Anyone got an idea what the issue so I can accurately search for a solution?

You know, understanding the problem is half the solution and that sort of thing…

Thanks!

@arnandegans Took a look at your robots.txt file and it shows:

User-agent: *
Disallow: /cgi-bin/
Disallow: /license.txt
Disallow: /readme.html
allow: /

Sitemap: http://mototravel.net/sitemap.xml

Should be something like:

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php

Sitemap: https://mototravel.net/sitemap.xml

Notice the https

Don’t know if this is even relevant, but may be something to look into. Your Disallow entries are not needed.

Could this possibly be a modsecurity issue?

I don’t know - I guess that’s what I’m asking you guys.
If I google the error I find all kinds of stuff for iOS apps and http/post requests, but nothing useful that applies to WordPress/ClassicPress and some talk about ‘symfony’ being outdated. Whatever that means.

If you have cPanel access, you should be able to turn off ModSecurity in order to try your update again. If it works with ModSec off, you should first turn it back on, then contact your webhost to see if they can tweak it so you can still have ModSec protection while also being able to save edits.

In any case, this seems to me to be a hosting environment issue, rather than a CP issue.

Its a VPS I have cPanel and WHM root access.
I’ll look for the option.

I too am not convinced its a CP issue, but my webhost is less than helpful. They barely answer tickets…

Found it, disabled it for all domains, waited a few seconds and tried to save my post a few times.
Still not working.

Can it be a firewall thing? And if so, how do I check that?
As far as I know, aside from regular updates to cPanel, that’s the only thing that got messed with in the past 6 months.

If it was ModSec issue, it would have made an immediate difference.
Could be a firewall issue; it definitely has to do with security.
Sorry I don’t have the expertise to be more helpful.

Seems to be a browser issue involving a javascript conflict. Have you seen this?