Paul Hammant's Blog: CORS vulnerabilities
Back in 1997, I coded a Java applet that was a postable “form”. I used the <applet/> tag parameter data to describe the names of the fields, in the form, their types, whether they were mandatory or not, and the applet adjusted its size to fit. When complete the form would post an email via an open SMTP service (port 25) back to the employer’s staff. That was for car or house insurance quotes, and the boss didn’t really like it (and had not asked for it), so it never went live. It was all moot, within a number of months the browser-makers agreed that things served up on a domain/port would be restricted in respect of irregular domain/port usages. The “Same Origin Policy” (SOP) was born.
CORS (Cross-Origin Resource Sharing)
POSTing a HTML form over HTTP(S) served up on one domain to another, has always been possible. CORS though brings back some of the fine-grained capabilities of that pre-SOP era. Read about CORS on wikipedia or Mozilla Dev Network. The skinny is that modern CORS-compatible web servers and browsers can negotiate over pre-configured URLs that can bust out of the SOP restrictions like we could in the early days. These days nobody develops Java applets, a JavaScript microframeworks rule the roost.
Serverless programming
Technologies like CouchDB can be installed an configured as a canonical data store, and seamlessly provide sophisticated query capabilities for JSON documents help within. Pages that would use that can be served statically from a different domain, and via Angular (etc) can interact with the data in the former. Maybe your dot-com is not going to launch in that style, but whole classes of Lotus-Notes style applications can have a highly economic life developed that way. Never mind serverless, it is programmer-less application development that is within reach.
Unauthorized access to CORS data (problem).
Context
Say you had an Angular (etc) app on https://foo.example.com. Say, via CORS, it is reading and writing data to https://yourAccount.bigCORSservice.com/foo/ relying on the latter being configured at a CORS level to exclusively speak to the former.
Note: Angular’s first pre-Google use was “Get Angular” which concentrated on the hosting of data as a service as much as Angular itself.
Problem
Anyone could spoof their own /etc/hosts
entry to masquerade (in our example) foo.example.com and route to 127.0.0.1 to gain access to all the data held at yourAccount.bigCORSservice.com/foo, but with a completely different web-application application interoperating with it.
Going further, someone could write some simple Python (etc) logic to open sockets to the CORS server in question and do all the handshaking necessary to have open access to the data within.
Both of these are possible if the sole CORS restriction is to the allowed a domain (rather than just wildcard = “*”). Meaning someone can sidstep the entry level of CORS restricting that can be coded in server side config.
Solution
Secure Authentication is needed, both for the read-only usage of the CORS accessible data and for modifications to it. Unless the data is relatively public, in which you’d authenticate the user only for write, update, or delete. That too has a caveat - there are some classes of data that you’re happy to wiki-style updated without authentication (and don’t care if they are vandalized from time to time).
Caveats
Regardless of the /etc/hosts trickery I talk about above, a hackers version of Firefox or Chrome could easily incorrectly honor its half of the CORS negotiation to make data similarly masquerade on the accessing domain. Neither of those two are vulnerabilities for random visitors to websites (unless the CORS server operator configured “*” for allowed domains). They are only vulnerability to your data, and the end-user (hacker) has gone to some level to set it up.
“*” and CORS community advice
Site enable-cors.org has a ‘server’ page. Their advice presently, suggests “*” for Apache, AppEngine, ASP.NET, AWS, CGI Scripts, ExpressJS, IIS 6 & 7, Meteor, Nginx, Perl PSGI scripts, PHP, ColdFusion, Tomcat, WCF. As a suggestion, asterisk is the most wide open configuration, and is not helpful. Only enable-cors.org’s Virtuoso page mentions alternate domain configurations but none of those pages steps further into authentication or differential r/w permissions.
With an asterisk configuration of the CORS server, it is possible for anyone else to mount a website in public, that can interoperate with your data just as well as your application can. Of course that’s only true if your CORS server is mounted on the public internet. Even if you authenticate against that data, the “*” mounting of it, allows for third-parties to deploy first class applications interoperating with your data.
Conclusion.
This isn’t really a true vulnerability, just a feature of technology that you should consider. Someone, on their own desktop system, can make your data more open that you intended it if you malcofigured your CORS server. Explicitly you should consider read and write access behind a formal login/authentication to the CORS server by default, and soften that only after conversations about sensitivity and approved usage of the data (or modification to it).
It is possible too - that browser makers should pop-up a dialog box regardless - “Site foo.example.com is reading (or writing) data from cross-origin server at yourAccount.bigCORSservice.com/foo, do you consent to let it do this - Yes | Yes and remember this decision | No”.