CORS anywhere

A proof-of-concept

Who hasn't felt the same way? You want to access a web service API and display the scraped data on your own web page, but your browser doesn't allow it. The security feature CORS (cross-origin resource sharing) makes it impossible if the webservice does not include the respective headers. Isn't it there a way around it?

Since CORS is only a security feature that is checked on the client-side browser, it can be bypassed very easily. For example, by installing the browser plugin Allow CORS. This plugin includes the CORS headers to all responses to the browser, thus enabling the browser to happily display and include all cross-origin resources. However, this is not very elegant since every user who wants to use the website has to install this plugin. Another way around is to route the requests of the website through a proxy that sets the relevant CORS headers in the response of the webservice. In doing so, the proxy can be configured once and for all users. Clients do not have to install a plugin which would leverage already good security features of the browser.

Such a proxy is for example cors-anywhere by Rob--W. Robs proxy is well documented and he included several examples of how to install and use the CORS proxy. I wanted to try his proxy and set up a small system with a webservice, two webapps (one without the proxy, the other with CORS proxy) a DNS server for name resolution and the CORS proxy server itself.

This system may seem complicated at first glance, however it reflects a natural setup: A webapp that wants to include resources from a webservice which is hosted on another domain. If all server would run on the local host, there wouldn't be a problem - hence the DNS server is necessary to give different names to the systems. Only the use of different host names causes the browser not to include different resources without problems.

The systems are simulated with docker containers. Docker container are small, encapsulated systems, similar to virtual machines. The only difference is that they are much smaller and more resource-efficient. Setup and usage of the container is extremely easy. However, knowledge with the command line is an advantage. A writeup how to initialise the docker container is available here.

If everything is set up, the system should look something like this (is it just me, or does this look like the millennium falcon?):

Without the CORS-proxy, the client could not access the data from the host "nagoya-foundation.com" since the CORS restrictions deny sharing the resources to a web-app that runs on another host ("tokyo-foundation.com"). However, with the CORS-proxy, the respective CORS headers are set, allowing the browser to include the resources.

Whoever wants to play with networks, docker container and web-apps should definitely try to recreate this setup. Learning about docker container, JavaScript programming and CORS was extremely fun and comes in handy for the next security assessment.