How to Trap Cors Errors

Is it possible to trap CORS errors?

See:

  • http://www.w3.org/TR/cors/#handling-a-response-to-a-cross-origin-request

...as well as notes in XHR Level 2 about CORS:

  • http://www.w3.org/TR/XMLHttpRequest2/

The information is intentionally filtered.

Edit many months later: A followup comment here asked for "why"; the anchor in the first link was missing a few characters which made it hard to see what part of the document I was referring to.

It's a security thing - an attempt to avoid exposing information in HTTP headers which might be sensitive. The W3C link about CORS says:

User agents must filter out all response headers other than those that are a simple response header or of which the field name is an ASCII case-insensitive match for one of the values of the Access-Control-Expose-Headers headers (if any), before exposing response headers to APIs defined in CORS API specifications.

That passage includes links for "simple response header", which lists Cache-Control, Content-Language, Content-Type, Expires, Last-Modified and Pragma. So those get passed. The "Access-Control-Expose-Headers headers" part lets the remote server expose other headers too by listing them in there. See the W3C documentation for more information.

Remember you have one origin - let's say that's the web page you've loaded in your browser, running some bit of JavaScript - and the script is making a request to another origin, which isn't ordinarily allowed because malware can do nasty things that way. So, the browser, running the script and performing the HTTP requests on its behalf, acts as gatekeeper.

The browser looks at the response from that "other origin" server and, if it doesn't seem to be "taking part" in CORS - the required headers are missing or malformed - then we're in a position of no trust. We can't be sure that the script running locally is acting in good faith, since it seems to be trying to contact servers that aren't expecting to be contacted in this way. The browser certainly shouldn't "leak" any sensitive information from that remote server by just passing its entire response to the script without filtering - that would basically be allowing a cross-origin request, of sorts. An information disclosure vulnerability would arise.

This can make debugging difficult, but it's a security vs usability tradeoff where, since the "user" is a developer in this context, security is given significant priority.

Catch CORS error

Use the onError event.

if(image.addEventListener) {
image.addEventListener('error', function (e) {
e.preventDefault(); // Prevent error from getting thrown
// Handle error here
});
} else {
// Old IE uses .attachEvent instead
image.attachEvent('onerror', function (e) {
// Handle error here
return false; // Prevent propagation
});
}

Code should probably be consolidated so you don't have to write your code twice, but hopefully you've got the idea.

Catching async exceptions from CORS request

Async exceptions on CORS requests sent via xhr can be caught by checking the onreadystatechange event.

xhr.onreadystatechange = ƒ(e) {
if (this.readyState === 4 && this.status === 200) {
try {
console.log('good');
}
catch (error) {
alert("There has been an error");
console.log(error);
return false;
}
callback();
}
else if (this.readyState === 4 && this.status !== 200) {
console.log('There has been an error');
}
};

Catching an Access-Control-Allow-Origin error in JavaScript

While browsers will log a more-detailed error message to the console, you can’t access that from your code. See https://bugs.chromium.org/p/chromium/issues/detail?id=118096#c5:

The details of errors of XHRs and Fetch API are not exposed to JavaScript for security reasons.

As far as the what specs actually require here, the Fetch spec is what defines the details of the “status message” to provide in case of an error — even if XHR is used instead of the Fetch API (the XHR spec references the Fetch spec). And for any network error or response blocked by the browser, the Fetch spec requires that the status message be “the empty byte sequence”:

A network error is a response whose status is always 0, status message is always the empty byte sequence, header list is always empty, body is always null, and trailer is always empty.

So all you can get back from any error you can catch is “TypeError: Failed to fetch” or such.

If you’re using XHR, all you have for handling an error is the onerror event handler:

xhr.onerror = function() { console.log("Error occurred but I dunno what exactly.")}

How to handle CORS error code?

The console message indicates that the server isn't sending the required Access-Control-Allow-Origin header when it sends the 401 response code.

You won't be able to use the CORS error handler to inject content into the DOM unless you fix that.

The server is likely sending the header correctly on responses with a 200 response code. It needs to do it for other response codes, though, if you wish to use data from those response codes.

Fix that on the server end before making design compromises on the client side. That may solve your problem straight away.

How to configure to handle CORS errors in web3 connecting to ganache

I figured out what was wrong and it was my fault. The web3 websocket provider does not enforce CORS so it can be used in my use case.

The issue I was having was that even though I change the protocol in the URI I sent web3, I was still asking for an HTTPProvider instead of a WebsocketProvider.

I made a few changes to getWeb3.js for my purposes like this...

const getWeb3 = (url) => {

...

if (url){
if (url.substring(0,2) === 'ws'){
const provider = new Web3.providers.WebsocketProvider(url);
const web3 = new Web3(provider);
console.log("Using WS URL for web3: ", url);
resolve(web3);
}
else {
const provider = new Web3.providers.HttpProvider(url);
const web3 = new Web3(provider);
console.log("Using HTTP URL for web3: ", url);
resolve(web3);
}
}

...
}

This worked fine.

On the plus side it made me understand CORS a lot better. I really don't like disabling anything in the browser.



Related Topics



Leave a reply



Submit