Save Ukraine

Adblockers as the reason of InvalidAccessError

Christian Kruse,

In reply to

The software is a web forum and the action could for example be a „mark this thread as read” action. This would send a POST AJAX request to a URL with a slug, e.g. /self/2015/oct/2/twitter-sponsored-links-ausblenden-mit-eigenem-user-punkt-punkt-punkt-css/mark_read.json. I could not find the problem, I wasn't even able to reproduce the problem, neither on production nor on the development system.

After a lot of hence and forth with the user and some carefully placed debugging code I was able to get the exception text: InvalidAccessError. I had a look at the standard and it stated:

Throws an InvalidAccessError exception if async is false, the JavaScript global environment is a document environment, and either the timeout attribute is not zero, the withCredentials attribute is true, or the responseType attribute is not the empty string.

This was weird. It is an async request, no CORS, no username/password. withCredentials was false, timeout was 0 and responseType was an empty string. For me there was no reason that this exception should be thrown. I even checked if the CSRF token was valid (it was). So I ignored this issue for some time, since I could not find a solution.

This evening I was finally able to reproduce the problem. While reading in the web forum suddenly I got the said error message. I fired up the inspector and checked what was going on. Totally weird: there was no request taking place, no network activity at all.

I fetched a database dump from production and restored it in development. This time I could reproduce the problem in development as well. So I spend a lot of time debugging, I even changed the URL the request was sent to – and bum, the request got through.

I was totally confused, what the heck was going on? I went step by step through the code for the gazillions time and this time I even stepped into XMLHTTPRequest.open(). And this time I saw a function called function block(m, u) in the call stack. And slowly it dawned to me: the request failed only on some URLs. This time the URL contained the keyword twitter. I use an ad blocker. Could it be…?

Quickly I disabled the ad blocker (I'm using uBlock) and re-tried – and this time the request went through without any problem. Wow! The ad blocker replaces XMLHttpRequest.open() by its own code and checks the request URLs for keywords on a block list. If the URL matches it would throw an InvalidAccessError.

This was really surprising for me. What a journey – it took me round about three months to find this problem.

Update: Having this tested with Chrome would have saved me a lot of time. Chrome explicitly states:

Failed to load resource: net::ERR_BLOCKED_BY_CLIENT

This error message is much more useful. Firefox, on the other hand, is as uninformative as Safari is: it just states error (even more generic than InvalidAccessError).