-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Relax origin header checking and add more CORS support #6644
Conversation
I have looked at both PRs and I really like having a separate CORS module. Using the express CORS module makes a lot of sense and adding pre-flight will be useful in the future (currently we only allow non-pre-flight requests). Big 👍 for separating concerns! The PR unfortunately disables all arrangements we had in place for disallowing requests from (unwanted) clients? I don't know if this is intentional or an oversight? Similar to Googles Maps API we wanted to only allow requests from certain origins. Removing these checks will allow to use client side JS to fetch content from any blog? Non CORS requests don't carry an origin header and are allowed by default. |
If I'm understanding what you're asking the answer is no, because if the client-side JS is coming from a non-trusted domain the response won't have an |
Here's a good way to test the behavior:
(You can also test that the |
You are right, that's what I love about Jason PRs :-D. I tried to recollect my memories if there was another reason for doing that but to no avail. It might had to do with trying to be smarter than the standards which is always a bad thing. Anyway, 👍 for merging! Would you like to combine the 2 PRs and/or put |
I think two distinct commits are beneficial because both changesets are working and it shows the evolution of the behavior. I'll "ref" this PR from #6646 unless someone else feels strongly about squashing both of these together. |
Refs #6642 - Do not send CORS headers on an invalid "origin" header, but otherwise allow the response to proceed normally. This enforces CORS for the browser but does not blow up non-CORS requests.
Refs #6644 - deps: cors@2.7.1; Add express cors package. - Adds new middleware for proper CORS support. - Handles CORS pre-flight checks. - Separates request authentication/authorization from CORS.
@sebgie Ok, this is all sorted out, rebased and ready to go. |
Sorry it took me so long to get back to this issue. I have tested it and it works great 👍. There is one thing left I noticed while testing. Previously it was possible to only add the hostname (without schema) to Is there a reason for doing this? It would break the installations of people who are currently using the API form another domain. |
It's because the scheme is part of the origin. When allowing cross-origin requests the ability to say If we want to make it the default to create a trusted domain for both |
I see ... But this is still going to break every existing API integration. Can we remove that for now and come up with a plan to do a migration for existing users after the release? I would really like to get this into 0.7.9? Would it make sense to add a HTTP and HTTPS field to the trusted domain table to and not store two lines per domain by default? Or can we think about it like our approach to SSL on the frontend and support HTTP + HTTPS by default and have a forceSSL column? |
Since this is a beta feature that exists only in labs and requires manually inserting records into the database, I think I'd be okay with noting the change in the release notes and updating the documentation.
I think simple is going to be better (i.e., one row per origin without any fancy http vs. https antics). Anything we can do to make the origin checking code simple is going to pay off long-term in regards to bugs and tears shed dealing with them. @ErisDS thoughts? |
This is a beta feature. If we agree that the current implementation is broken, and that this is the correct way to fix it, then I am in favour of just fixing it with release notes. My only concern is that there's no easy transition here. E.g. Upgrading Ghost & changing the trusted domain value have to be done independently, so there is always going to be a point (even if it's seconds) where it is broken. If there was a solution with a better transition path that would be interesting to me. Again though, if we're all happy that this is the right solution, then I say rip this plaster off. I can manually upgrade each user that has this on Ghost(Pro) and update their trusted domain records within seconds (it's not many) and each one of them has had explicit warning that this can break at any time. |
I'm definitely not against doing a migration (especially if it's just a one-off like the client secret fix)--just that I don't think we're obligated to jump through any hoops in this situation.
I think including the scheme as part of the origin is correct (but willing to discuss if there's dissent). Assuming there's consensus there, I don't know if we've settled on how to handle it. I'm in favor of doing a simple "one row per origin" solution so we can minimize the drama surrounding figuring out what's what, parsing URLs, and doing partial matches, etc., etc. But that's clearly just my opinion and I'm not sure @sebgie is on board with that. |
I definitely do not want to do a migration for this. No way. Buut, would a "transitionable fix" be to assume http for one version? So if the scheme is missing, bolt http on. Tell everyone they have to update their record for 0.7.9 and then do the break in 0.8.0. I literally just had this idea and I'm not even sure that I like it. Too much effort for something that is meant to break. |
I'm not sure we could assume just
Exactly. I'm not even sure we should bother. |
I'm aware that this is a labs feature and there is no obligation on our side to keep things working. Given that we are talking about the Public API which was anticipated for a long time I'm a bit hesitant to break it without discussion. If we agree that this is okay I'm fine with the PR as it is. |
Yah I'm ok with it. Anyone one Ghost(Pro) can't fix it themselves, but we can ensure it's done at the right time. Anyone who is self hosting should see the notice in the release notes. I've already added notice here: http://support.ghost.org/public-api-beta/ Worth keeping in mind that at some point we need to move & rename the |
As of this PR, we no longer have the following rules:
I assume this was done on purpose, but I'm not 100% clear on why they aren't needed anymore? |
They aren't needed for CORS purposes because if a request is cross-origin and doesn't match a Basically the only thing it was accomplishing was preventing same-origin requests that didn't match what was defined in |
Then the most common use case for In this case, the API would exist on This case is roughly the same as the Ghost(Pro) usecase - where the API exists on a different secure URL if you have a custom domain. The custom domain is what is output as I think if the hostname from |
If I understand the scenario(s) you're laying out then, yeah, I think we need to make an adjustment. To make cross-origin requests work where the frontend is at a different origin from the API by way of We should also add a test for this. |
refs TryGhost#6644 - urls specified in config.js should be considered whitelisted/trusted - this is not quite straightforward because config.js is not ready at the point the middleware is required - tests have been updated to cover these new cases + use rewire to override the internal whitelist cache
refs TryGhost#6644 - urls specified in config.js should be considered whitelisted/trusted - this is not quite straightforward because config.js is not ready at the point the middleware is required - tests have been updated to cover these new cases + use rewire to override the internal whitelist cache
Very much open to discussion. See #6642 (comment)