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

Allow to configure "allowed domains" for CORS on DAV #40537

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

susnux
Copy link
Contributor

@susnux susnux commented Sep 20, 2023

Summary

This adds CORS support to the DAV routes, the default is non breaking -> so no other domain is allowed.
But the admin can configure a list of allowed domains which will be allowed to access the DAV routes using CORS.

Moreover the admin can enable user defined lists, meaning that users can add their own allowed domains for WebDAV related requests, see #30964.

Why do we need CORS on DAV?

See #3131

Basically to access it within the browser from a different page, like e.g. the Dropbox file picker with allows you to pick files from your cloud onto another page (e.g. upload something from cloud to form etc).

Screenshot

Screenshot_20230920_150622

Todo

  • Follow-up: User config UI
  • Follow-up: allowed header UI
  • If this is decided: Write documentation

Checklist

* Exclude DAV CORS handling when no Origin specified
  This will exclude non-browser clients from CORS handling.
  Fixes some clients like davfs which break when CORS is enabled.
* fix: CORS on WebDAV is not working
  WebDAV is not working at all when used by on browser Javascript because the CORS headers
  are only present in the OPTION request, but not in the subsequent WebDAV methods.
  * This behavior is caused by a erroneous json_decode call while retriving the user's domains whitelist.
    It return an object, so the is_array always fails and no header are sent.
* Add Access-Control-Expose-Headers - to allow clients to access certain headers
* Adding many headers as allowed headers + add capability to read additional allowed headers from config.php
@susnux susnux added this to the Nextcloud 28 milestone Sep 20, 2023
@susnux susnux requested review from nickvergessen, skjnldsv, a team, ArtificialOwl and icewind1991 and removed request for a team September 20, 2023 13:15
I removed the beforeController logic here due to the change of handling CORS since PR 28457[1]

According to previous implementation, CORS was only allowed with methods that had @publicpage notation for preventing CSRF attacks.
But in the latest PR by me, the current implementations is as follows:

    * maintain a white-list of domains for whom CORS is enabled
    * This list can be viewed and edited under settings -> personal -> security

This implementation removes the need for `@PublicPage`[2].

[1] owncloud/core#28457
[2] owncloud/core#28864
@susnux susnux force-pushed the feat/cors-on-webdav branch from b0a6b70 to 6955c85 Compare September 20, 2023 13:18
@susnux susnux added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Sep 20, 2023
github-advanced-security[bot]

This comment was marked as outdated.

@susnux susnux force-pushed the feat/cors-on-webdav branch from 6955c85 to 4c2f7b1 Compare September 20, 2023 13:53
@susnux susnux changed the title Allow to configure trusted domains for CORS on DAV Allow to configure "allowed domains" for CORS on DAV Sep 20, 2023
Also make sure to only return allowed methods for DAV responses

Signed-off-by: Ferdinand Thiessen <[email protected]>
Signed-off-by: Ferdinand Thiessen <[email protected]>
Signed-off-by: Ferdinand Thiessen <[email protected]>
apps/dav/lib/Connector/Sabre/CorsPlugin.php Dismissed Show resolved Hide resolved
return;
}
} catch (\InvalidArgumentException $e) {
\OC::$server->getLogger()->debug('Invalid origin header was passed', ['Origin' => $originHeader, 'exception' => $e]);

Check notice

Code scanning / Psalm

DeprecatedMethod Note

The method OC\Server::getLogger has been marked as deprecated
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
\OC::$server->getLogger()->debug('Invalid origin header was passed', ['Origin' => $originHeader, 'exception' => $e]);
\OC::$server->get(LoggerInterface::class)->debug('Invalid origin header was passed', ['origin' => $originHeader, 'exception' => $e]);

apps/dav/lib/Connector/Sabre/CorsPlugin.php Dismissed Show dismissed Hide dismissed
apps/dav/lib/Connector/Sabre/CorsPlugin.php Dismissed Show dismissed Hide dismissed
@@ -130,6 +131,8 @@
$this->server->addPlugin(new ProfilerPlugin($this->request));
$this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig()));
$this->server->addPlugin(new AnonymousOptionsPlugin());
$this->server->addPlugin(new CorsPlugin(\OC::$server->getUserSession(), \OC::$server->getConfig()));

Check notice

Code scanning / Psalm

DeprecatedMethod Note

The method OC\Server::getUserSession has been marked as deprecated
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you can change to:

Suggested change
$this->server->addPlugin(new CorsPlugin(\OC::$server->getUserSession(), \OC::$server->getConfig()));
$this->server->addPlugin(new CorsPlugin(\OC::$server->get(IUserSession), \OC::$server->get(IConfig::class)));

With:

use \OCP\IConfig;
use \OCP\IUserSession

apps/dav/lib/Server.php Dismissed Show dismissed Hide dismissed
* @return DataResponse
*/
public function updateUserEnabled($value) {
if (!is_bool($value)) {

Check notice

Code scanning / Psalm

DocblockTypeContradiction Note

Docblock-defined type bool for $value is always bool

// Reach here if it's valid
$response = new \OC\OCS\Result(null, 100, 'OPTIONS request successful');
\OC_Response::setOptionsRequestHeaders($response, $this->config);

Check failure

Code scanning / Psalm

InvalidArgument Error

Argument 1 of OC_Response::setOptionsRequestHeaders expects OCP\AppFramework\Http\Response<int, array<string, mixed>>|Sabre\HTTP\ResponseInterface, but OC\OCS\Result provided
@nickvergessen nickvergessen removed their request for review September 21, 2023 08:37
@skjnldsv skjnldsv removed their request for review September 22, 2023 09:16
@skjnldsv

This comment was marked as resolved.

@susnux susnux requested a review from Altahrim September 22, 2023 09:57
@skjnldsv skjnldsv mentioned this pull request Nov 1, 2023
This was referenced Nov 6, 2023
This was referenced Nov 14, 2023
@blizzz blizzz modified the milestones: Nextcloud 28, Nextcloud 29 Nov 23, 2023
This was referenced Mar 12, 2024
This was referenced Mar 20, 2024
@skjnldsv skjnldsv mentioned this pull request Mar 28, 2024
81 tasks
@skjnldsv skjnldsv modified the milestones: Nextcloud 29, Nextcloud 30 Mar 28, 2024
@skjnldsv skjnldsv added 2. developing Work in progress stale Ticket or PR with no recent activity and removed 3. to review Waiting for reviews labels Jul 27, 2024
This was referenced Jul 30, 2024
This was referenced Aug 5, 2024
@skjnldsv skjnldsv mentioned this pull request Aug 13, 2024
@skjnldsv skjnldsv removed this from the Nextcloud 30 milestone Aug 14, 2024
@aleixq
Copy link

aleixq commented Aug 14, 2024

I am coming from #37716 for which I was proposing #37896 .
If the reason to allow dav cors is to make it easier to offer a filepicker, I think that filesharing api and filepreview api may be covered to be allowed in a similar way too. If not it will be a raw basic one IMHO.
By now the way to offer a functional filepicker is to use the webapppassword app as it also includes the filesharing api extended and preview api extended, for which I made the accepted PR some time ago when I was trying to offer Nextcloud as a DAM for a CMS (drupal).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2. developing Work in progress enhancement feature: dav security stale Ticket or PR with no recent activity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cors origin allowed list check CORS setting at user level Support for cross-domain WebDAV access (CORS)
7 participants