Talk: Enabling CORs on graphql

Created on 9 Oct 2018  路  8Comments  路  Source: coralproject/talk

Hi!

I'm looking to access Talk's gql so I can re-use the data in another React app - going to have a go at making a user profile widget. This would also be applicable to obtaining comment counts, which I'm currently running through a proxy.

I first tried to add it via a server plugin by adding CORs middleware to the /api/v1/graph/ql route, but you can't add middleware after the initial call to graphqlExpress and the plugin router bindings get called after the main api responses.

That makes good sense, but it seems that CORs will need to be added as an option in Talk core for this to work, or add an earlier point for talk plugins to inject express middleware but I'm not sure that has many/any other use.

Alternatively I could stick my custom Talk embed in an iFrame but I'm shooting to have modals so ideally not an iframe. Also I may be overlooking a way to swap out everything in the existing embed except all of the data binding but it looks pretty tied to being loaded on a particular asset with a comment feed, so it still seems like CORs gql hookup would be best.

So perhaps we add a server option named something like TALK_TRUSTED_CORS_ORIGINS that is a comma delimited string of whitelisted origins for CORs. Not required and default undefined so CORs remains off by default. Probably should also be added as middleware to the entire express app instead of just api/v1/graph/* unless there is a reason not to.

Thanks!

question

Most helpful comment

As all external requests made to Coral must have an admin token, it is not possible to make this request in the browser. Instead, the request should be made from a server.

All 8 comments

We would strongly discourage the use of CORS across the board, as it introduces a variety of security issues and vulnerabilities.

We've seen news sites that have embedded Talk inside sidebars, and modals as well, and the iFrame is probably the best place to display it.

If you just want to get some data, we'd recommend creating a plugin that exposes a single route with the appropriate data and CORS headers for that particular response, thereby limiting the attack surface.

@wyattjoh Ok cool I can probably use an iFrame and be all set then. Took me writing out the issue to realize that was even an option. Went down quite the rabbit hole with CORs haha.

Thanks for taking a look!

@wyattjoh could you elaborate on the "security issues and vulnerabilities"?

Sure @philippbosch! We store parts of the authentication state on the host site's local storage (via the postMessage bridge). As a platform, we're designing Talk to run on other sites, that can be easily embedded, which creates a sticky situation.

Some scripts running on news sites may not be considered completely under their control (such as advertising or tracking javascript). In order to secure the way that Talk interacts, all interactions with the API are done from inside the iFrame, where CORS does not have to be enabled. If we started experimenting with CORS, we could run into situations where the Talk platform could be targeted by XSS attacks that could take the access token we store there, and start generating comments directly on the Talk platform in essentially a DDOS style.

By prohibiting the use of CORS, we're simply reducing the attack surface. Knowing though that there are likely situations where a newsroom would want to load a particular piece of information for another part of the page, we would recommend creating a plugin that serves only the particular data you want to injest via a route, and only settings CORS headers on that route along with a Access-Control-Max-Age: -1 set to ensure that the CORS status is not cached.

@wyattjoh Does this still apply for the V5 graphql api? As per the docs (https://docs.coralproject.net/talk/v5/integrating/cms/) it seems that the new way to do CMS integration is through the graphql api. However, when using apollo-client the preflight request returns a 405. Is this not the correct approach?

As all external requests made to Coral must have an admin token, it is not possible to make this request in the browser. Instead, the request should be made from a server.

@wyattjoh I find that comment a little confusing, as I have been following the SSO documentation here: https://coralproject-docs-talk.netlify.app/talk/v5/integrating/sso/#external-integrations

And by creating a jwt following the steps outlined in those docs I am able to authenticate a request to the graphql server as the user defined in the JWT (creates a user if they dont exist and everything).

Meaning not all external request require an admin token.

I am currently also trying to implement graphql client on react for coral talk api but running into cors issues as well, namely not being able to execute preflight requests.

As a security feature, we do not and are not planning on allowing CORS headers to be set, as all in-browser requests to Coral should be made from within the Coral iFrame or be sent from a server that isn't subject to the CORS restrictions.

Tokens created through the SSO documentation can be used to execute requests yes. In production deployments, Coral generates all the queries that the application uses and whitelists them on the server. Any other GraphQL request made that is not a persisted GraphQL query must be sent using an Admin token. A regular Commentor token will not have the right permission to make a non-persisted GraphQL query.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

allanassis picture allanassis  路  3Comments

mattlinares picture mattlinares  路  5Comments

schwabing picture schwabing  路  5Comments

cristiandean picture cristiandean  路  5Comments

cristiandean picture cristiandean  路  3Comments