Re: [cors] JAX-RS and preflight
Jonas, Let me circle back to the top now and see if I can play this back. 1. Of course, when writing a server, it's up to me to implement access control decisions. 2. To protect a plethora of poorly-protected servers out there, CORS puts an additional level of access control in clients. 3. To expose resources cross-origin, my service has to reassure the client that it does, indeed, know what it is doing. That reassurance is delivers via the CORS headers. 4. There's a impedance mismatch between the CORS model of resource control, which is URI+method, and the JAX-RS model, which adds other headers. 5. A server thus must return CORS indications at the level of URI+method. This 'opens the door' in the client -- and then the server is responsible for imposing any fine-grained access control that it wants at the level of the other headers. --benson On Thu, Dec 1, 2011 at 8:07 PM, Jonas Sicking jo...@sicking.cc wrote: On Thu, Dec 1, 2011 at 4:35 PM, Benson Margulies bimargul...@gmail.com wrote: Here's where I am not following: If I am trying to protect a server, I will look at the request, and if I don't like it, I will return a 401. Period. I'm happy to have the Origin header to help me do that. I don't see what the rest of the complex processing does for me. As someone aware of CORS the rest of the processing doesn't really do anything for you. However, imagine that you set up your server 5 years ago. Or that you weren't aware of the existence of CORS. Then you obviously wouldn't be looking at the Origin header. Or return a 401. You would just gladly server whatever request that was posed to you. This is why CORS has additional checks in the client. To ensure that servers that aren't aware of CORS don't return any sensitive information to the requesting page, or that the requesting page can't case sensitive side effects on the server. In particular, would I delegate the work to the CORS client? How do I know that the client really implements the spec? Consider 'Expose-Headers' ... If I don't want them to go to a particular origin, why would I bother to return all this metadata in a preflight instead of, well, just not returning them? Am I just trying to make it easier for client-side processes to understand my rules? The idea is to give you plenty of tools to make it easy to protect yourself. If you have lots of code running on your server and you are not fully sure what all of it does, but you still want to expose some specific header to the requesting page, you simply whitelist that header. That way you don't have to worry about making the rest of your code foolproof. So while you can provide belts, we'll still provide suspenders :-) / Jonas
Re: [cors] JAX-RS and preflight
On Fri, Dec 2, 2011 at 5:29 AM, Benson Margulies bimargul...@gmail.com wrote: Jonas, Let me circle back to the top now and see if I can play this back. 1. Of course, when writing a server, it's up to me to implement access control decisions. 2. To protect a plethora of poorly-protected servers out there, CORS puts an additional level of access control in clients. 3. To expose resources cross-origin, my service has to reassure the client that it does, indeed, know what it is doing. That reassurance is delivers via the CORS headers. Correct so far. 4. There's a impedance mismatch between the CORS model of resource control, which is URI+method, and the JAX-RS model, which adds other headers. CORS provides the ability for fine-grained opt-in to various aspects of http. This so that you can choose which parts of http you want to guarantee that you have secured in your server-side scripts. I.e. CORS isn't simply a on/off switch requiring perfect knowledge of everything you do on your server in order to flip to the on mode. However the fine-grained opt-in is only so fine-grained. We don't for example have the ability to say I'm only fine with receiving the x-my-header header if it contains one of the following values, or say I only want to expose the x-my-response-header if it isn't doesn't start with 'user-id:. Similarly, we don't provide the values of any headers when making the preflight OPTIONS request. My english isn't good enough to say if this qualifies as an impidence mismatch or not (wikipedia was unhelpful [1]). But I agree that it means that means that you have to do some security checks in the code that handles the request, and can't rely exclusively on CORS enforcing your security model. [1] http://en.wikipedia.org/wiki/Impedance_mismatch 5. A server thus must return CORS indications at the level of URI+method. This 'opens the door' in the client -- and then the server is responsible for imposing any fine-grained access control that it wants at the level of the other headers. Yup. / Jonas
[cors] JAX-RS and preflight
There's a problem with REST-ful services, as exemplified by the JAX-RS standard, and CORS as drafted. A JAX-RS server names a resource, in part, via the content-type of a request. A POST with content-type of application/json names a different resource (in as much as it selects a different method to call) that a POST with content-type text/plain. The problem here is that a preflight OPTIONS is defined to *not* pass the content type unless it is simple. Thus, the service implementation can't reliably tell what resource is under discussion. As things are, a service would have to take a common posture for all preflights given the URL and Accept(-*) headers, and ignoring the content type. Would you consider defining an Ac-Request-Content-Type header to pass a non-simple content type on a preflight?
Re: [cors] JAX-RS and preflight
On 2011-12-01 21:20, Benson Margulies wrote: There's a problem with REST-ful services, as exemplified by the JAX-RS standard, and CORS as drafted. A JAX-RS server names a resource, in part, via the content-type of a request. A POST with content-type of application/json names a different resource (in as much as it selects a different method to call) that a POST with content-type text/plain. That seems to be entirely JAX-RS problem. The *resource* is supposed to be identified by the request-URI. The problem here is that a preflight OPTIONS is defined to *not* pass the content type unless it is simple. Thus, the service implementation can't reliably tell what resource is under discussion. Even if OPTIONS would be sent with a Content-Type header field, that field, by definition, would identify the internet media type of the request body. As things are, a service would have to take a common posture for all preflights given the URL and Accept(-*) headers, and ignoring the content type. Absolutely. Would you consider defining an Ac-Request-Content-Type header to pass a non-simple content type on a preflight? Unless I'm missing something here you are definitively trying to do the wrong thing. Best regards, Julian
Re: [cors] JAX-RS and preflight
Let me try to present this more clearly. First of all, I did not design or implement JAX-RS itself. The committee that designed it might have done something wrong in their dispatching approach. However, *I* am merely working on implementing a facility for the resource side of CORS in a JAX-RS framework. Perhaps it would be less disturbing if I characterized the situation as follows: JAX-RS dispatches the job of serving content at a smaller granularity than an HTTP/CORS 'resource'. It operates on the combination of resource+content-type+accepts+accepts-language. All of those facts are available to a preflight except for the content type when the content-type is non-simple. My humble request is for you to consider defining one more 'request' header for preflight: access-control-request-content-type -- that the client would send to the server on the OPTIONS command. There are many, many, services written with JAX-RS -- representing a classic case of that old standardization chestnut: 'existing practice.' What I'm proposing here would be trivial for client implementations, so I would think that the authors of the CORS proposal would at least grant this idea a full 5 minutes of thought before rejecting it. Obviously, if you do reject this, it will not be the end of the internet as we know it. On Thu, Dec 1, 2011 at 3:57 PM, Julian Reschke julian.resc...@gmx.de wrote: On 2011-12-01 21:20, Benson Margulies wrote: There's a problem with REST-ful services, as exemplified by the JAX-RS standard, and CORS as drafted. A JAX-RS server names a resource, in part, via the content-type of a request. A POST with content-type of application/json names a different resource (in as much as it selects a different method to call) that a POST with content-type text/plain. That seems to be entirely JAX-RS problem. The *resource* is supposed to be identified by the request-URI. The problem here is that a preflight OPTIONS is defined to *not* pass the content type unless it is simple. Thus, the service implementation can't reliably tell what resource is under discussion. Even if OPTIONS would be sent with a Content-Type header field, that field, by definition, would identify the internet media type of the request body. As things are, a service would have to take a common posture for all preflights given the URL and Accept(-*) headers, and ignoring the content type. Absolutely. Would you consider defining an Ac-Request-Content-Type header to pass a non-simple content type on a preflight? Unless I'm missing something here you are definitively trying to do the wrong thing. Best regards, Julian
Re: [cors] JAX-RS and preflight
On 2011-12-02 00:11, Benson Margulies wrote: Let me try to present this more clearly. First of all, I did not design or implement JAX-RS itself. The committee that designed it might have done something wrong in their dispatching approach. However, *I* am merely working on implementing a facility for the resource side of CORS in a JAX-RS framework. And I have to admit that I'm a member of that Expert Group. Apparently not paying sufficient attention, though. Perhaps it would be less disturbing if I characterized the situation as follows: JAX-RS dispatches the job of serving content at a smaller granularity than an HTTP/CORS 'resource'. It operates on the combination of resource+content-type+accepts+accepts-language. Varying the *response* based on Accept and Accept-Language is ok. It doesn't change the resource you're talking to, though. Content-Type really doesn't belong into this at all. All of those facts are available to a preflight except for the content type when the content-type is non-simple. That may be true, but doesn't affect what HTTP resource you're talking to. My humble request is for you to consider defining one more 'request' header for preflight: access-control-request-content-type -- that the client would send to the server on the OPTIONS command. There are many, many, services written with JAX-RS -- representing a classic case of that old standardization chestnut: 'existing practice.' What I'm proposing here would be trivial for client implementations, so I would think that the authors of the CORS proposal would at least grant this idea a full 5 minutes of thought before rejecting it. Please don't. It's totally the wrong thing to do here. If JAX-RS takes the position that the Content-Type on a request affects the resource being identified it totally needs to be fixed. ... Best regards, Julian
Re: [cors] JAX-RS and preflight
On Thu, Dec 1, 2011 at 12:20 PM, Benson Margulies bimargul...@gmail.com wrote: There's a problem with REST-ful services, as exemplified by the JAX-RS standard, and CORS as drafted. A JAX-RS server names a resource, in part, via the content-type of a request. A POST with content-type of application/json names a different resource (in as much as it selects a different method to call) that a POST with content-type text/plain. The problem here is that a preflight OPTIONS is defined to *not* pass the content type unless it is simple. Thus, the service implementation can't reliably tell what resource is under discussion. As things are, a service would have to take a common posture for all preflights given the URL and Accept(-*) headers, and ignoring the content type. Would you consider defining an Ac-Request-Content-Type header to pass a non-simple content type on a preflight? You can always allow the OPTIONS request and make the security decision once you get the actual request. The main point of the OPTIONS request is to protect servers that aren't aware of CORS at all. Clearly a CORS+JAX-RS doesn't fall into this category. / Jonas
Re: [cors] JAX-RS and preflight
On Thu, Dec 1, 2011 at 6:53 PM, Jonas Sicking jo...@sicking.cc wrote: On Thu, Dec 1, 2011 at 12:20 PM, Benson Margulies bimargul...@gmail.com wrote: There's a problem with REST-ful services, as exemplified by the JAX-RS standard, and CORS as drafted. A JAX-RS server names a resource, in part, via the content-type of a request. A POST with content-type of application/json names a different resource (in as much as it selects a different method to call) that a POST with content-type text/plain. The problem here is that a preflight OPTIONS is defined to *not* pass the content type unless it is simple. Thus, the service implementation can't reliably tell what resource is under discussion. As things are, a service would have to take a common posture for all preflights given the URL and Accept(-*) headers, and ignoring the content type. Would you consider defining an Ac-Request-Content-Type header to pass a non-simple content type on a preflight? You can always allow the OPTIONS request and make the security decision once you get the actual request. Sure, if the server is the concerned party but The main point of the OPTIONS request is to protect servers that aren't aware of CORS at all. Clearly a CORS+JAX-RS doesn't fall into this category. As a superannuated security person, I thought that the point of CORS was to protect clients from cross-scripting pranks of web pages, not to protect servers from anything. Nothing in CORS involves returning a 401. Wouldn't the actual access decision be made on the server instead of on the client if we were protecting the server? Why return all this stuff to the client instead of failing requests or censoring headers? Something tells me that there's a theory here that I haven't read yet. / Jonas
Re: [cors] JAX-RS and preflight
On Thu, Dec 1, 2011 at 4:14 PM, Benson Margulies bimargul...@gmail.com wrote: On Thu, Dec 1, 2011 at 6:53 PM, Jonas Sicking jo...@sicking.cc wrote: On Thu, Dec 1, 2011 at 12:20 PM, Benson Margulies bimargul...@gmail.com wrote: There's a problem with REST-ful services, as exemplified by the JAX-RS standard, and CORS as drafted. A JAX-RS server names a resource, in part, via the content-type of a request. A POST with content-type of application/json names a different resource (in as much as it selects a different method to call) that a POST with content-type text/plain. The problem here is that a preflight OPTIONS is defined to *not* pass the content type unless it is simple. Thus, the service implementation can't reliably tell what resource is under discussion. As things are, a service would have to take a common posture for all preflights given the URL and Accept(-*) headers, and ignoring the content type. Would you consider defining an Ac-Request-Content-Type header to pass a non-simple content type on a preflight? You can always allow the OPTIONS request and make the security decision once you get the actual request. Sure, if the server is the concerned party but The main point of the OPTIONS request is to protect servers that aren't aware of CORS at all. Clearly a CORS+JAX-RS doesn't fall into this category. As a superannuated security person, I thought that the point of CORS was to protect clients from cross-scripting pranks of web pages, not to protect servers from anything. Nothing in CORS involves returning a 401. Wouldn't the actual access decision be made on the server instead of on the client if we were protecting the server? Why return all this stuff to the client instead of failing requests or censoring headers? Something tells me that there's a theory here that I haven't read yet. CORS isn't intended to fix cross-scripting pranks at all. At least if you are referring to the traditional meaning of XSS attacks. The intent of CORS is to allow websites to communicate with other servers without exposing existing web servers to new attack vectors. Specifically to CSRF-like attacks. So CORS is very much designed to protect (or rather not harm) servers. Not to do anything related to XSS. However, in allowing websites to talk to other servers in a safe manner, it removes the need to use script elements to do so. This use of script elements has traditionally opened up websites to XSS attack vectors. So while CORS isn't designed to protect against XSS attacks, it does obsolete XSS sensitive technology. I hope that makes sense? / Jonas