Comparison of CORS and UMP
From Web Security
A Comparison of CORS and Uniform Messaging Policy
CORS and UMP differ in their design philosophy: CORS extends the design of the Same Origin Policy; whereas UMP provides a clean slate upon which a variety of access-control mechanisms can be implemented. The Same Origin Policy presupposes an ACL mechanism where access decisions are based on the user's identity as expressed in various credentials, such as HTTP cookies. Client code is unable to opt-out of this mechanism, since HTTP cookies and other credentials are always automatically included in every request by the user-agent. This design suffers from a number of problems, such as Cross-Site-Request-Forgery and similar attacks. In contrast, the UMP doesn't automatically augment requests with additional access-control information, leaving the requesting content in control of what credentials or other kinds of tokens it wishes to use in a request.
In CORS, each resource declares a set of origins, which are able to issue various kinds of requests (such as DELETE requests) for the resource and to read the contents of the resource. For example, consider a case where the operators of foo.example.com want to grant the operators of bar.example.net the ability to issue requests to a user's http://foo.example.com/user123/pony resource. The operators of foo.example.com grant this access by including the header "Access-Control-Allow-Origin: http://bar.example.net" in response to requests that bear the user's credentials.
The above design has a number of problems:
- clickjacking: An attack page can induce the user to interact with the resource in an undesired way by using a transparent <iframe> of the http://foo.example.com/user123/pony resource
- CSRF-like: In addition to foo.example.com, bar.example.net also has access to resources at attack.example.org. When informing bar.example.net of the URL for a shared resource, attack.example.org provides the URL http://foo.example.com/user123/pony. Consequently, bar.example.net mistakenly deletes a resource at foo.example.com, when it was expecting to delete a resource at attack.example.org.
- unenforceable security policy: If a response representation uses the JSON format, its content can be accessed cross-origin using the <script> tag. So if the response to a GET request on the http://foo.example.com/user123/pony resource is JSON, the content can be accessed by any domain, regardless of the security policy expressed in the response header "Access-Control-Allow-Origin: http://bar.example.net". This contradiction will likely be surprising for web developers.
Although UMP doesn't specify any particular access-control mechanism, the non-normative sections of the specification encourage authors to use permission tokens, instead of credentials. A permission token provides specific access to a specific resource; whereas a credential provides all of a user's access to a set of resources. The UMP also does not recommend any particular mechanism for using permission tokens: an OAUTH-like design or a web-key design are plausible choices. In a web-key design, the resource discussed in the previous section might have a URL like: https://foo.example.com/user123/?s=mhbqcmmva5ja3 . The foo.example.com operator would respond to requests with the response header: "Access-Control-Allow-Origin: *".
This design avoid the problems in the discussed CORS design:
- clickjacking: This attack is not possible, since the attacker does not know the URL to use in the transparent <iframe>.
- CSRF-like: This attack is not possible, since the attacker does not know the URL for the resource at foo.example.com
- unenforceable security policy: The UMP response header does not claim greater protection than can be provided.
UMP as subset of CORS
As discussed, UMP enables cross-domain messaging by reducing the information automatically added to requests by a user-agent, rather than augmenting it. Consequently, it is feasible to specify UMP as a subset of CORS. This subset should have the following characteristics:
- The existence of an UMP API in user-agents does not endanger any resource that conforms only to CORS.
- The existence of a CORS API in user-agents does not endanger any resource that conforms only to UMP.
- If a CORS resource accepts requests that happen to be uniform requests, an UMP API can successfully message with the CORS resource. A CORS resource might not accept such requests if it requires cookies, an Origin header with a value other than "null", or limits responses to a particular Origin.
Given the above characteristics, a developer can read only UMP and ignore CORS, yet still create safe code. This code can successfully message with CORS resources that do not require credentials. UMP is therefore a way of messaging with the credential-free subset of CORS resources.
CORS itself identifies a subset similar to UMP with its credentials flag. It is possible the "false" value of this flag, in combination with a way of setting the Origin header to "null", will eventually offer all the functionality of UMP. Today, there are several open issues against CORS that obscure this possibility.
In addition to the above characteristics, it is possible, though not necessarily desirable, to enable further compatibility with:
- If an UMP resource accepts non-uniform requests, a CORS API with the credentials flag set to "true" can be used to message with that UMP resource. An UMP resource might not accept such requests as a technique to detect CSRF-like vulnerabilities in clients. Though it might be safe for such a client to send a non-uniform request to an UMP resource, sending the same request to a CORS resource might result in a CSRF-like vulnerability. By rejecting the request, the UMP resource enables detection of such bugs.
The UMP specification reproduces the use-cases from the CORS specification and notes any that present implementation difficulties.
[Describe various use cases for these protocols.]
- Client-side access to a database on a separate HTTP server. This use case involves reading and writing information from the database.
[Explain how to use CORS and UMP to address each of the use cases]
[For each protocol, examine the security risks in using that protocol to address its use case]
[Summarize the high-level bits from the document]
User Agents Implementing CORS
- WhenCanIUse implementation data:
- Chrome - since version 12.0
- Firefox - since version 4.0
- Safari - since version 4.0
- iOS Safari - since version 3.2
- Android Browser - since version 2.1
- Internet Explorer - IE10
- Opera; see 28-Oct-2011 Blog by Charles McCathieNevile regarding Opera's implementation plans
Sites that Use CORS
- TwitPic -- see the illustrative demo and the TwitPic API documentation.
- This example is actually an UMP example, not a CORS example, since it:
- only uses POST requests of multipart/form-data
- responses only use "Access-Control-Allow-Origin: *"
- permission tokens are explicitly sent in the body of the request, instead of in cookies
- This example is actually an UMP example, not a CORS example, since it:
- enable-cors.org - includes a short tutorial for adding CORS support to Apache and a service to check if a site is CORS-enabled. Also enumerates some services using CORS
User agent support for UMP
- Caja: see 22-Apr-2010 email from Mark Miller
- Chrome; see 10-May-2010 email from Dirk Pranke
- Firefox; see 19-Apr-2010 email from Jonas Sicking
- XDomainRequest - Microsoft's XDomainRequest Object (XDR); proposed for standardization at W3C in March 2008
- CORS slide deck; presented by Maciej during WebApps 3-November-2009 f2f meeting
- GuestXHR; 4-Nov-2009 by Mark Miller and Tyler Close
- CORS, UMP and XHR by John Kemp (1-Jun-2010)
Links to CORS tutorials, how-to's etc.:
- CORS for XHR in IE10; IEBlog; 9-Feb-2012
- Using CORS to load WebGL textures from cross-domain images; Hacks.Mozilla.Com; 8-Nov-2011