Skip to content
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

Add cors middleware #8504

Merged
merged 2 commits into from
May 11, 2014
Merged

Add cors middleware #8504

merged 2 commits into from
May 11, 2014

Conversation

BernhardPosselt
Copy link
Contributor

This adds another middleware that adds a preflighted CORS request to your base controller class and enforces strict security for CORS requests in your app to not allow CSRF

To make your controller method respond to a CORS request, extend from ApiController and simply annotate it with @cors
To enable the preflighted CORS OPTIONS request for all urls starting with /api/v0.2/, add something like this to your routes where ApiController is present

array('name' => 'api#preflighted_cors', 'url' => '/api/v0.2/{path}', 'verb' => 'OPTIONS', 'requirements' => array('path' => '.+')),

CORS is used to allow webapps and websites to access your API methods and can be a potential threat for CSRF.

More information on that https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

@LukasReschke @MorrisJobke @LEDfan @DeepDiver1975 @tanghus @cosenal

@karlitschek
Copy link
Contributor

Sorry but we don´t want to dumb more libraries in the ownCloud core only because they might be useful. Apps are free to ship components like that if they want to use it. At the later stage if 4-5 apps ship the same component in the exact same version then we might consider to add the to the ownCloud core, or not.
👎

@BernhardPosselt
Copy link
Contributor Author

Well i see a need in particular for the music app that also exposes an API (shiva), concering other apps thats why im currently mentioning them at the top.

@LukasReschke
Copy link
Member

I certainly see a reason for a properly implemented CORS middleware. Such security related components shouldn't get implemented by every single application because it's too easy to do it wrong (TM). As this middleware in the AppFramework namespace it shouldn't hurt core itself too much ;-)

That said, I didn't took a proper look at the source yet but if @karlitschek reconsiders his vote I'm more than happy to review this properly together with @Raydiation.

@BernhardPosselt
Copy link
Contributor Author

Without the test its basically 15 lines of code and does not affect any other part of owncloud btw.

@karlitschek
Copy link
Contributor

It does affect us because if it is in core then we always have to maintain it, fix potential security things, maintain compatibility because it is part of the ownCloud public app api then. And so on. So adding things like that comes with a cost.

Please use it in the apps directly for now. And if it becomes common practice that everyone is using it then we can check if it is worth to save a few bytes of code in ownCloud and add it to the core. At the moment there is no need.

@BernhardPosselt
Copy link
Contributor Author

@karlitschek can i leave the PR open until enough people vote for it in here then?

@LukasReschke
Copy link
Member

Mhm, this middleware and the one in notes/news allows any website to access the API. This is very bad.

@Raydiation

@LukasReschke
Copy link
Member

It does affect us because if it is in core then we always have to maintain it, fix potential security things,

And this is exactly why we should have this in core. The proposed solution suffers from a security flaw as Access-Control-Allow-Credentials allows any site to send the cookies with the request which leads to a CSRF like vulnerability in notes and news. (any website you visit can access your private data)

Without this pull request this would most likely also propagated into other apps (e.g. the music player). Thanks to it we had the chance to review this and discuss the security implications together.

If even @Raydiation makes this fault it's likely that others are doing it to and we should try to prevent that. With a centralised solution we can at least try to make the life easier for developers so that they won't unintentional introduce critical security bugs.

Regarding the fact that this is really not much code and that unit tests are provided I'd advocate for the inclusion of this into core.

@karlitschek
Copy link
Contributor

guys, if there are security problems in apps then the next step is to fix them. this is a way later discussion if we include _another_library in the owncloud core which should be small and not bloated

@BernhardPosselt
Copy link
Contributor Author

@karlitschek middleware is now private and always registered and prevents CSRF via web api if an app implements cors by itself. Apart from that it should offer a sane/secure (needs review) default way to do this

PS: Test fail because I need a previous PR to go in beforehand because I cache an expensive operation now which speeds up execution

@BernhardPosselt
Copy link
Contributor Author

@LukasReschke please review if the current implementation is safe :) (will fix it for notes and news afterwards then)

@karlitschek is the appstore problem fixed? I can't release a security update otherwise

@BernhardPosselt
Copy link
Contributor Author

To adress the 'bloat' argument:

CORS is the only way to make ownCloud API's work on web plattforms such as:

  • FirefoxOS
  • ChromeOS
  • Any Webapp
  • Windows 8 apps
  • Browser addons that interact with ownCloud
  • Any other platform that runs on a browser engine

Since ownCloud is essentially a giant API that is used to sync stuff across devices I think providing a default implementation for CORS is at least as valid of an argument as providing a default CSRF and OAuth implementation. Leaving this to app developers (like me) will lead to potential security problems (like news and notes). Adding this to core will allow us to make it easy for developers to make their ownCloud API available on web platforms and allow us to further spread the acceptance of ownCloud as a synchronization service alternative.

The current implementation is one additional function that gets called, and only called if you use @cors (which would happen anyways if you do it on your own) and ensures that the request is handled in a secure manner. In addition there is a default controller method implementation that allows you to define your access rules (headers, verbs) for each resource seperately.

@jancborchardt

$middleware = new CORSMiddleware($request, $this->reflector);

$response = new Response();
$response->addHeader('AcCess-control-Allow-Credentials ', 'TRUE');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AcC ?? 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont know how browsers handle http headers, I think theyre treatet in a case insensitive way, thats why this test tries to that edge case ;)

@jancborchardt
Copy link
Member

This seems a very important part of making it possible for external app developers (especially web apps) to integrate with ownCloud.

Also see the »ownCloud as a backend for web apps« concept at https://github.com/owncloud/core/wiki/Project-ideas#owncloud-as-backend-for-web-apps
cc @michielbdejong

@michielbdejong
Copy link
Contributor

@Raydiation wrote:

CORS is the only way to make ownCloud API's work on web plattforms

Yes! I fully agree.

Cross-origin user data is very important indeed. I'll help you in any way I can to add cors headers to your API. I can mentor a GSOC student for instance, or come to a hackathon to work on it, or whatever is useful.

@karlitschek
Copy link
Contributor

I'm not saying this is not useful, secure, good code or in other ways helpful. But this doesn't mean that we should dump all useful code into the core. The design goal of the owncloud core is to be as small as possible. In fact it is already too big. So if this is useful then we should use it for the news app API first and perhaps other apps. This doesn't mean that we have to dump it into the core to make it heavier, difficult to maintain and to keep stable

@BernhardPosselt
Copy link
Contributor Author

@karlitschek I'm fully aware of that. For me personally it is in fact easier to maintain my own version since i don't have to go through the whole PR process for adding and maintaining the feature.

BUT: If I propose a feature via a PR I expect from the reviewer to seriously look at the problem and give me proper feedback. I don't want to start a basic discussion about code in general and why less code is better than more code, I want to solve a problem or share things with fellow developers. Now if, in any case, you'd depend or use the App Framework for any of your apps I'd be very grateful for your opinion and if you think it would fix your problem, if you think this should be easy enough and trivial enough to not do it in core and let it implement each individual app author. But this kind of argumentation will get us nowhere and is VERY frustrating for me as a contributor. If you don't want to read into the code or documentation by yourself, please let someone else that you trust take a look at it.

@BernhardPosselt
Copy link
Contributor Author

As in please dont:

meh, new code that i dont need

but rather:

can you explain why this is needed?
what is this used for?
is there an alternative implementation?

Edit: If of course you're interested in it

@ghost
Copy link

ghost commented May 8, 2014

💣 Test Failed. 💣
Refer to this link for build results: https://ci.owncloud.org/job/pull-request-analyser/4645/

@tanghus
Copy link
Contributor

tanghus commented May 9, 2014

As it has been - wisely - decided to move the AppFramework to core, I am interested in having it both lean, but more importantly usable and secure. Therefore I prefer to have great implementations which are closely scrutinized for security issues.
A security issue that would be present in at least 3 apps has already been detected. I think that speaks for itself for including it in core.

remove methodannotationreader namespace

fix namespace for server container

fix tests

fail if with cors credentials header is set to true, implement a reusable preflighted cors method in the controller baseclass, make corsmiddleware private and register it for every request

remove uneeded  local in cors middleware registratio

dont uppercase cors to easily use it from routes

fix indention

comment fixes

explicitely set allow credentials header to false

dont depend on better controllers PR, fix that stuff later

split cors methods to be in a seperate controller for exposing apis

remove protected definitions from apicontroller since controller has it
@ghost
Copy link

ghost commented May 9, 2014

🚀 Test Passed. 🚀
Refer to this link for build results: https://ci.owncloud.org/job/pull-request-analyser/4681/

@tanghus
Copy link
Contributor

tanghus commented May 10, 2014

In case my point didn't come clearly thru, as I may sometimes try to soften my views when putting them into words.

The design goal of the owncloud core is to be as small as possible. In fact it is already too big.

Recommendable, but what does that exactly mean? What is not needed in core? archive, migration, memcache, ocs, vobject, activitymanager, api, avatar, backgroundjob, cache, contactsmanager, tags, eventsource or files for that matter? Plus everything else under /apps. Fine, lets scrap it and start from scratch. I can actually mention a few that I wouldn't be missed (including some of my contributions), but that's another matter.

Design-wise it would probably be good, but we would be left with basically nothing.

Some of the good decisions that have been made during the past ~1½ year - from my PoV - are

  • The strict adherence to interfaces in new contributions
  • The introduction of the Server "container"
  • The (partly) inclusion of the AppFramework.

Those - and other - changes can make it possible to actually move towards a mature, trustworthy codebase.
I have no special attachments to including CORS middleware, but I understand from several parties, that I trust, that it is a small, yet important part to include, and rejecting it as bloat is both disrespectful and counter-productive. So my rant is not about CORS - it's about the culture and attitude that I sometimes see in this community. What I seen is community members reluctant to voice their opinions for improvements.
To say it straight out: The community should have priority over both "The Inc." and "The Founder". Otherwise it's not a community anymore, and I don't see a place for myself in it.
Alternatively the two quoted nouns could find better ways for making compromises - without compromising the project - pun intended ;)
If none of those objects are met I frighten for the future culture of this project, but so be it; I find another place to try to keep my mind sound, because quite honestly recently it has done quite the opposite[*]

[*] With exceptions of course. No one mentioned, no one forgotten.

PS: I've tried to keep this rant in a sober tone, although my state might not be so (otherwise I probably wouldn't have written it) and I expect any responses to it to be made in public.
/cc @jospoortvliet @jancborchardt

@karlitschek
Copy link
Contributor

@tanghus Thanks a lot. I don´t think this has anything to do with Inc. or anything else.
This is purely about the long term maintainability of the core. And this is something anything who wants that ownCloud still exists in 5-10 years should care about.
We all know several other projects where this framework/libraries bloat went wrong.

@karlitschek
Copy link
Contributor

O.K. Let´s put this into core under this conditions:

  • Full documentation how this should be used by app developers is available on doc.owncloud.org at the same time.
  • At least two independent apps are fully ported to use this.
  • @Raydiation maintains this for the time being exactly as the rest of the app framework.
  • Someone actively
  • Someone starts to port other pieces of ownCloud to use this so that we don´t have code duplication.

Additionally we should also regularly check which code, frameworks or dependencies in core can be removed. Otherwise we run into a long term problem.

@BernhardPosselt
Copy link
Contributor Author

  • documentation up in my PR: Getting app dev docs up to date for ownCloud 7 owncloud-archive/documentation#340 been holding off putting work into it until this was clear to be accepted
  • Independent as in different app authors or apps that dont depend on each other (like calendar and contacts). Also requiring concrete usage as a precondition for a merge into the development branch is kinda rough, you'll end up breaking backwards compability if you put it into master and otherwise maintain different branches depending on what API level you want to support with one codebase. What is the goal if the requirement? Do you just want a test brancht to check if it works?
  • If I add it I'll use it, you've also seen me fixing all the appframework bugs after I've ported my apps (none of which were introcuded by me btw)
  • ?
  • Cant comment on the last one, it seems a bit close to start porting when feature freeze is approaching. Do you just want a commitment? Code duplication seems impossible to prevent IMO if we want to be backwards compatible.

@tanghus
Copy link
Contributor

tanghus commented May 10, 2014

Full documentation how this should be used by app developers is available on doc.owncloud.org
at the same time.

Reasonable and preferable.

At least two independent apps are fully ported to use this.

I believe that should be the case for oC7 or oC8. Longterm dev is of essence.

@Raydiation maintains this for the time being exactly as the rest of the app framework.

I think this should be rephrased to "there must always be an active, responsible maintainer." which is documented in the source file. I don't know if there's a @maintainer tag in http://www.phpdoc.org/ ?
That it should always be @Raydiation counts out the bus-factor ;)
Also where would that that place all other core developers including you Frank? We have git blame and I've been personally hit by that recently ;)

Someone actively

Meaning what? If it's correct it doesn't have to change. This correlates with the maintainer or other developers related to this.

Someone starts to port other pieces of ownCloud to use this so that we don´t have code duplication.

Agreed.

Additionally we should also regularly check which code, frameworks or dependencies in core can be removed. Otherwise we run into a long term problem.

This should be addressed in a separate issue and I'm sorry @Raydiation that I kinda hijacked this issue for that.

@karlitschek
Copy link
Contributor

documentation up in my PR: owncloud-archive/documentation#340 been holding off putting work into it until this was clear to be accepted

thanks a lot

Independent as in different app authors or apps that dont depend on each other (like calendar and contacts). Also requiring concrete usage as a precondition for a merge into the development branch is kinda rough, you'll end up breaking backwards compability if you put it into master and otherwise maintain different branches depending on what API level you want to support with one codebase. What is the goal if the requirement? Do you just want a test brancht to check if it works?

In KDE for example is the rule that a library has to be used by at least two independent apps before it can go into kdelibs. I think this makes sense. It is not enough to just merge it into core and then later depend on someone else to actually use it. This hould be done in parallel also as a reality check to see if the API works.
Please also note that master is not really a development branch at the moment. It will be frozen and become ownCloud 7 very soon. So development should happen in a different branch and only stuff that is ready for ownCloud 7 should go into master.

If I add it I'll use it, you've also seen me fixing all the appframework bugs after I've ported my apps (none of which were introcuded by me btw)

O.K. Great. And welcome to the wonderful world of being a maintainer. We have to feel responsible for the software and also fix bugs from other people. ;-)

?

Sorry. Formating fuck up. :-)

Cant comment on the last one, it seems a bit close to start porting when feature freeze is approaching. Do you just want a commitment? Code duplication seems impossible to prevent IMO if we want to be backwards compatible.

Sure. It is fine to keep old code for compatibility reasons. But a commitment to keep on using this code and porting other pieces would be nice of course

@tanghus
Copy link
Contributor

tanghus commented May 10, 2014

This is purely about the long term maintainability of the core. And this is something anything who wants that ownCloud still exists in 5-10 years should care about.

To be very forthright I'm not not sure which ownCloud you mean here? Is it to be sure independent developers can produce efficient and secure code, or is it to secure that the Inc. have less dependencies when they use their paid work force to make solid apps for paying customers?
The arguments and motives have become too opaque for me, and after 2½ years of mostly enjoying this project, I'll have to retract myself from it.

@Raydiation again for misusing this PR.

@karlitschek
Copy link
Contributor

@tanghus I´m not really sure what you mean here. Like I said this has nothing to do with Inc. or anything else.
We all have invested a lot of time and energy into ownCloud. So it is in our all interested that the ownCloud core and the apps will be maintainable and stable and working and mostly bugfree for as long as possible. Because of that we have to do some quality check when architectural changes are done in the core. I think this is good maintainership in general.

private $request;

/**
* @param string $request the name of the method that will be called on
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be a IRequest instead of a string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

@scrutinizer-notifier
Copy link

A new inspection was created.

@BernhardPosselt BernhardPosselt added this to the ownCloud 7 milestone May 11, 2014
@scrutinizer-notifier
Copy link

The inspection completed: 8 new issues, 28 updated code elements

@ghost
Copy link

ghost commented May 11, 2014

🚀 Test Passed. 🚀
Refer to this link for build results: https://ci.owncloud.org/job/pull-request-analyser/4690/

@LukasReschke
Copy link
Member

👍 once the mentioned requirements are fulfilled.

@BernhardPosselt
Copy link
Contributor Author

As for the two independent apps: Notes and News will depend on this.

The music shiva API should also benefit from this, that is if @MorrisJobke wants to make the API work with web applications.

Any requirements left?

@LukasReschke
Copy link
Member

Another reviewer is left ;-)

@karlitschek
Copy link
Contributor

👍 from me as discussed

BernhardPosselt pushed a commit that referenced this pull request May 11, 2014
@BernhardPosselt BernhardPosselt merged commit a252f59 into master May 11, 2014
@BernhardPosselt BernhardPosselt deleted the cors-middleware branch May 11, 2014 14:54
@MorrisJobke
Copy link
Contributor

Sorry. I didn't get to read thorugh the whole thread. I like to have a security-wise review of such critical code. I will also use this for shiva and the other parts of the API because @jbtbnl started to build a mobile app (with phonegap AFAIK) which will need to have this.

Thanks @Raydiation

@LukasReschke
Copy link
Member

Sorry. I didn't get to read thorugh the whole thread. I like to have a security-wise review of such critical code.

Guess who did that ;-)

@MorrisJobke
Copy link
Contributor

Guess who did that ;-)

That's what I meant. ;)

I read through the discussions and would also like to have that in core.

@LukasReschke
Copy link
Member

Ahh - misunderstood you. Sorry 🍺

@jancborchardt
Copy link
Member

Thank you everyone! :)

@lock lock bot locked as resolved and limited conversation to collaborators Aug 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants