read-write-web / rww-play

read write web Play
59 stars 19 forks source link

Avoid usage of Access-Control-Allow-Origin:* when possible #118

Open slorber opened 10 years ago

slorber commented 10 years ago

See reasons here: https://github.com/linkeddata/rdflib.js/pull/35

XMLHttpRequest cannot load https://www.stample.io/srv/cors?url=http%3A%2F%2Fbblfish.net%2Fpeople%2Fhenry%2Fcard. 
Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. 
It must be 'true' to allow credentials.

It seems the credentials flag is required for Firefox. Since this flag is added in RDFLib the responses for other domain resources must add a new Access-Control-Allow-Credentials: true.

But with this flag, we can't use a wildcard for Access-Control-Allow-Origin

OPTIONS https://sebas5.stample.io/card 
Wildcards cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. 
Origin 'http://cimba.co' is therefore not allowed access. jquery.min.js:5

So, for requests on other domains with credentials flag = true (now it's rdflib.js default)

This works:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:https://sebastien1.localhost:8443

This doesn't work:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:*

So I think we should try to avoid using the wildcard when it's possible and fix the allowed domains.

For serving RWW resources we should probably use the acl:origin (with a fallback to request Origin header maybe?). I don't see this implemented yet and it seems we use a * in controllers.ldp.ReadWriteWebControllerGeneric#writeGetResult

For the CORS proxy we should probably do something similar. The actual code handles it not so badly: Access-Control-Allow-Origin: {value sent by remote resource, falling back to request Origin header value, falling back to *}, except for error handling so error body may not be available to the client.

What do you think @bblfish

bblfish commented 10 years ago

we need to study the CORS spec carefully, so that we don't create security holes

annevk commented 9 years ago

Why do you want to set withCredentials to true? For non-credentialed resources * is the best policy.

bblfish commented 9 years ago

@annevk I was going to write about this to the webappsec mailing list but then found out about COWL ... which brings a whole new dimension to the problem.

But in short we are building Linked Data apps to build a distributed Social Web. The apps can go around the web and follow links to get data in some rdf format such as json-ld, and use this data to build a dynamic User Interface (see the main wiki, eg my Scala-Exchange talk on how to do this). Now such a client cannot know if the resources on remote servers are access controlled or not. It will depend, on each resource. Some are public, others not. On a privacy aware social web, many resources will be protected.

As a result it does not seem that CORS is really adapted for this type of application. How would a server know what agents to give access to when in the end users may be using JS agents with as many different origins as there are users? One answer would be for the server to look in the WebID Profile for a relation relating the user to origins he trusts. But this won't work in CORS because the access controlled resources first need to go through the pre-flight request that does not allow client authentication ( as I understand at the moment ). So really for efficiency reasons the proxy will have to take on the role of making all these decisions, logging in to remote servers for the user, and fetching resources directly. We have a number of ways we can do that with WebID Authorization Delegation for example.

But perhaps COWL will help us fill in some of the missing bits. I read that COWL was part of the next webappsec working group charter...

annevk commented 9 years ago

@bblfish it's totally fine to always allow CORS preflight from any origin and then do something different for the actual resource. All CORS preflight does is making sure that the URL "speaks" CORS, it doesn't really grant anything beyond that, just making sure no unsuspecting servers are compromised by complex requests.

And it's totally fine to allow requests from all origins too and instead use a token of sorts to identify who has access. That's actually preferred as capability-based security doesn't have ambient authority flaws.

bblfish commented 9 years ago

Ah ok, that's good to know. That will help finish the code for PR #133 - where we were having a more recent discussion on the topic. That should do for now. ( I do look forward for a time where we could have a system that removed preflight requests, and the odd limitation against posting json-ld ( or other rdf formats ) )

annevk commented 9 years ago

If you don't understand the current system I recommend reading https://annevankesteren.nl/2015/02/same-origin-policy

However, there are no limitations in terms of submission formats. Just anything non-legacy requires a CORS preflight. We're working out some strategy to cache them for an entire origin rather than just a URL, but they will remain in place forever unless there's some fundamental shift in network architectures, which seems unlikely.

bblfish commented 8 years ago

This may already be done correctly. The work I did recently to get HTTP-Signature to work forced me to fix quite a lot of things here. So this just requires to be checked.