1

RFC 7231, Section 3.1.1.5 states:

A sender that generates a message containing a payload body SHOULD generate a Content-Type header field in that message unless the intended media type of the enclosed representation is unknown to the sender. If a Content-Type header field is not present, the recipient MAY either assume a media type of application/octet-stream ([RFC2046], Section 4.5.1) or examine the data to determine its type.

The CORS recommendation states:

A header is said to be a simple header if the header field name is an ASCII case-insensitive match for Accept, Accept-Language, or Content-Language or if it is an ASCII case-insensitive match for Content-Type and the header field value media type (excluding parameters) is an ASCII case-insensitive match for application/x-www-form-urlencoded, multipart/form-data, or text/plain.

This seems to create a non-specified case for CORS implementations on POST, because using application/octet-stream forces the non-simple header case, and 'examining the data to determine its type' is not trivial.

What is the most reasonable thing to do in the following cases?

  • Content-Length of request is 0. (I'd like to assume Content-Type: text/plain to enable the simple header case.)
  • Content-Length is non-zero. (Default to application/octet-stream and force non-simple header case?)

In order to address a comment relating to whether CORS is a security measure or just a model for resource sharing, I'm adding some additional information regarding the implications of these edge cases. Yes, CORS is certainly a model for resource sharing. However, resource sharing worked just fine without CORS, until HTTP clients added security measures to explicitly prevent cross-origin resource retrieval. If implemented improperly, the server-side component of CORS can re-open some of those security holes by improperly sharing resources, especially where credentials are involved. These edge cases are paths that (depending on the answer to the above questions) lead directly to the section on whether to allow cross-origin requests for resources with credentials.

Determining what constitutes a simple header vs. a non-simple header in the above edge cases affects whether some requests are considered simple requests or not, which in turn brings Part 4: Security Considerations into effect:

A simple cross-origin request has been defined as congruent with those which may be generated by currently deployed user agents that do not conform to this specification. Simple cross-origin requests generated outside this specification (such as cross-origin form submissions using GET or POST or cross-origin GET requests resulting from script elements) typically include user credentials, so resources conforming to this specification must always be prepared to expect simple cross-origin requests with credentials.

Because of this, resources for which simple requests have significance other than retrieval must protect themselves from Cross-Site Request Forgery (CSRF) by requiring the inclusion of an unguessable token in the explicitly provided content of the request.

Parker
  • 400
  • 1
  • 3
  • 15

1 Answers1

4

The main idea behind the content-type restriction is that XMLHttpRequest with CORS should not weaken the default security compared to what already can be done within the traditional security model. The traditional security model allowed the following cross-origin requests:

  • Simple GET requests created by the browser. That is no payload and thus also no Content-type header.
  • POST requests created by submitting forms. These have a payload but the Content-type (attribute enctype) could only be application/x-www-form-urlencoded, multipart/form-data or text/plain.

Anything outside of what could be done with such simple requests and form submissions must be handled more strict by default so that no new attack vector gets created. This includes any kind of custom header and any setting for content-type which are not sent by the browser by its own.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • This is a great, simple answer that got my thinking back on track for how to address the relations between the two standards. I wish some of this reasoning were included in the CORS Recommendation. – Parker Feb 25 '16 at 12:11