nextcloud / nextcloud/server

[Bug]: files_external virtual folders may shadow similarly named user folder, causing sync clients to potentially clobber users' files

Open
#45,019 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

0. Needs triage 28-feedback bug feature: external storage feature: sharing hotspot: filename handling
Dominant language
PHP
Stars
36.9k
Forks
5.2k
Avg merge
2d 3h
Merged PRs (30d)
713

Description

⚠️ This issue respects the following points: ⚠️
Bug description

By using the files_external app, an admin user may create virtual folders backed by an external data store, and publish that folder to multiple users. If such a virtual folder has the same name as a folder any user the external folder is being shared with, the external folder is given priority and the user's own, identically named folder becomes inaccessible.

Neither the Nextcloud server, nor the files_external app, nor the user's sync client (on Windows) notices this; instead, the sync client sees the folder's new content, assumes that another device or the web-app has changed the content, and begins syncing the user's locally stored files with the external folder's content. If the external folder is marked as read-only, or if Nextcloud can for some reason not create new files in the external folder's store, the user's local files are deleted instead.

In order to restore the locally clobbered files, the user requires the admin's help to either rename, remove or unshare the external folder, or disable the files_external app entirely. In either case, the user's personal folder can then be accessed again, and remote files are unchanged.

Steps to reproduce
  1. Setup a Nextcloud AIO instance, admin user, regular user, and Windows machine with the Nextcloud sync client.
  2. As the regular user, create a folder /Test and file /Test/user-file in Nextcloud.
  3. Login to Nextcloud as the regular user with the Windows sync client and sync the testfolder.
  4. As the admin user, enable the files_external app.
  5. Create an external folder named Test and map it to any external storage space that contains a file external-file.
  6. Share the newly created external folder with the regular user.

After a while, the regular user's sync client will silently delete user-file and download external-file. The user cannot access the non-external folder through either the sync client or the web interface.

Expected behavior

The files_external app should not prevent access to a user's own folder, even when an external folder of the same name is created.

Some suggested behaviours:

  1. Warn the admin user, when the admin attempts to share an external folder with a user who already has a folder of the same name and prevent the external folder from being shared with that user. Can have wildly complex knock-on problems, e.g. when an ext. folder is shared with a group and a user is added to that group.
  2. Give priority to folders existing in the user's personal storage. The user will not be able to access the external folder until they have explicitly removed or renamed the conflicting user-owned folder, but they will also not lose any local copies or be forced to re-download potentially large amounts of data.
  3. Introduce a technical separation between user content and app-provided content, such as files_external folders.
Installation method

Official All-in-One appliance

Nextcloud Server version

28

Operating system

None

PHP engine version

None

Web server

None

Database engine version

None

Is this bug present after an update or on a fresh install?

Fresh Nextcloud Server install

Are you using the Nextcloud Server Encryption module?

Encryption is Disabled

What user-backends are you using?
  • Default user-backend (database)
  • LDAP/ Active Directory
  • SSO - SAML
  • Other
Configuration report
{
    "system": {
        "one-click-instance": true,
        "one-click-instance.user-limit": 100,
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [
            {
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/custom_apps",
                "url": "\/custom_apps",
                "writable": true
            }
        ],
        "check_data_directory_permissions": false,
        "memcache.distributed": "\\OC\\Memcache\\Redis",
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "password": "***REMOVED SENSITIVE VALUE***",
            "port": 6379
        },
        "overwritehost": "cloud.my.domain.net",
        "overwriteprotocol": "https",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "localhost",
            "cloud.my.domain.net"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "pgsql",
        "version": "28.0.4.1",
        "overwrite.cli.url": "https:\/\/cloud.my.domain.net\/",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbport": "",
        "dbtableprefix": "oc_",
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "maintenance": false,
        "updater.release.channel": "stable",
        "updatedirectory": "\/nc-updater",
        "loglevel": "2",
        "log_type": "file",
        "logfile": "\/var\/www\/html\/data\/nextcloud.log",
        "log_rotate_size": "10485760",
        "log.condition": {
            "apps": [
                "admin_audit"
            ]
        },
        "preview_max_x": "2048",
        "preview_max_y": "2048",
        "jpeg_quality": "60",
        "enabledPreviewProviders": {
            "1": "OC\\Preview\\Image",
            "2": "OC\\Preview\\MarkDown",
            "3": "OC\\Preview\\MP3",
            "4": "OC\\Preview\\TXT",
            "5": "OC\\Preview\\OpenDocument",
            "6": "OC\\Preview\\Movie",
            "7": "OC\\Preview\\Krita"
        },
        "enable_previews": true,
        "upgrade.disable-web": true,
        "mail_smtpmode": "smtp",
        "trashbin_retention_obligation": "auto, 30",
        "versions_retention_obligation": "auto, 30",
        "activity_expire_days": "30",
        "simpleSignUpLink.shown": false,
        "share_folder": "\/Shared",
        "one-click-instance.link": "https:\/\/nextcloud.com\/all-in-one\/",
        "upgrade.cli-upgrade-link": "https:\/\/github.com\/nextcloud\/all-in-one\/discussions\/2726",
        "htaccess.RewriteBase": "\/",
        "files_external_allow_create_new_local": true,
        "trusted_proxies": "***REMOVED SENSITIVE VALUE***",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_sendmailmode": "smtp",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpport": "465",
        "default_phone_region": "DE",
        "bulkupload.enabled": false,
        "davstorage.request_timeout": 3600,
        "dbpersistent": false,
        "appsallowlist": false,
        "allow_local_remote_servers": true,
        "maintenance_window_start": 100,
        "mail_smtpauth": 1,
        "mail_smtpsecure": "ssl",
        "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
        "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
        "defaultapp": ""
    }
}
List of activated Apps
Enabled:
  - activity: 2.20.0
  - admin_audit: 1.18.0
  - bruteforcesettings: 2.8.0
  - calendar: 4.7.0
  - cloud_federation_api: 1.11.0
  - contacts: 5.5.3
  - contactsinteraction: 1.9.0
  - dav: 1.29.1
  - federatedfilesharing: 1.18.0
  - files: 2.0.0
  - files_pdfviewer: 2.9.0
  - files_reminders: 1.1.0
  - files_sharing: 1.20.0
  - files_trashbin: 1.18.0
  - files_versions: 1.21.0
  - firstrunwizard: 2.17.0
  - logreader: 2.13.0
  - lookup_server_connector: 1.16.0
  - mail: 3.6.0
  - nextcloud-aio: 0.5.0
  - nextcloud_announcements: 1.17.0
  - notifications: 2.16.0
  - notify_push: 0.6.10
  - oauth2: 1.16.3
  - password_policy: 1.18.0
  - provisioning_api: 1.18.0
  - serverinfo: 1.18.0
  - settings: 1.10.1
  - sharebymail: 1.18.0
  - support: 1.11.1
  - text: 3.9.1
  - theming: 2.3.0
  - twofactor_backupcodes: 1.17.0
  - twofactor_totp: 10.0.0-beta.2
  - twofactor_webauthn: 1.4.0
  - unroundedcorners: 1.1.3
  - viewer: 2.2.0
  - workflowengine: 2.10.0
Disabled:
  - circles: 28.0.0 (installed 27.0.1)
  - comments: 1.18.0 (installed 1.17.0)
  - dashboard: 7.8.0 (installed 7.7.0)
  - encryption: 2.16.0
  - federation: 1.18.0 (installed 1.17.0)
  - files_external: 1.20.0 (installed 1.20.0)
  - photos: 2.4.0 (installed 2.3.0)
  - privacy: 1.12.0 (installed 1.11.0)
  - recommendations: 2.0.0 (installed 1.6.0)
  - related_resources: 1.3.0 (installed 1.2.0)
  - survey_client: 1.16.0 (installed 1.15.0)
  - suspicious_login: 6.0.0
  - systemtags: 1.18.0 (installed 1.17.0)
  - user_ldap: 1.19.0
  - user_status: 1.8.1 (installed 1.7.0)
  - weather_status: 1.8.0 (installed 1.7.0)
Nextcloud Signing status
No errors have been found.
Nextcloud Logs
I do not wish to make logs available publicly due to privacy concerns. If any reputable contributors wish to review my logs, I'm happy to provide full logs privately.
Additional info

The files_external app is disabled because the app list was taken from my live instance after I had encountered the problem and restored access to my files.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in the files_external app and reproduce the collision using the issue's virtual-folder and personal-folder steps. No source file or test is named, so first trace how shared external folders are resolved against personal folders and decide which expected behavior is intended. Done should include regression coverage showing that a same-named external folder cannot shadow or clobber the user's folder.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.