fix: check for the identifier alias for the storage backend#41538
Conversation
|
Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes. |
DeepDiver1975
left a comment
There was a problem hiding this comment.
- can you add unit tests?
- please add changelog items
fa639a3 to
5080fc6
Compare
ec4554e to
88fcb18
Compare
DeepDiver1975
left a comment
There was a problem hiding this comment.
- I miss tests where local storage mounting is allowed.files_external_allow_create_new_local => true
- did you double check if the http status code change 422 -> 403 has any impact on the frontend. technically this is a breaking change to the api
I don't think it's possible to trigger the behavior from the web UI. If the backend isn't visible, it won't show up in the frontend and it won't be selectable. The change in the HTTP code should match the previous behavior: it returns a 403 if the user tries to create or update a backend that he isn't allowed to use. It also makes more sense to return a 403 error in those circumstances.
They should be covered. For the global / user storage controllers, the tests have the flag enabled by default, so all those tests run with that setting. The only exception are the "new" |
looking at the changeset - I see files_external_allow_create_new_local only being removed from the code - is this setting actually still be checked anywhere? |
I prefer 'are' over 'should' - assertion over assumption |
It's used in the settings page. The flag is in an awkward position... it doesn't allow the creation of the local storage from the frontend, but the admin can still create the local storage via API. Regular users won't be able to setup local storages anyway. I'll try to add an |
just to be sure: the backend has to verify everything - ignore frontend beahavior. |
Without the visibility, the admin won't be able to create local storages, and the previously created local mounts will be hidden and inaccessible
7039820 to
45ffc86
Compare
|
There might be slightly changes in the behavior with the PR because the checks have been moved to visibility. If the backend isn't visible for someone, this means that the mount point (if any) will be hidden and won't appear (it won't be accessible), and creating or updating new mounts with the backend won't be possible. To remark, if the backend becomes visible at a later date, previously existing hidden mounts will reappear. Specifically, for the local storage, it will be blacklisted for regular users and it will never have the visibility for regular users. Admins will require the |
Code ReviewOverviewThe PR fixes a security bypass: the original code checked What's Good
Issues1. Missing test cases for the allowed path (also raised by @DeepDiver1975) There are no tests where 2. The new controller tests may not exercise the right code path The old controller check ran at request time. The new check runs at registration time ( 3. Breaking HTTP status code change: 422 → 403
4. Type annotation inconsistency in /** @var IConfig */
private IConfig $config; // typed property (PHP 7.4+)
/** @var bool */
private $allowUserMounting = null; // @var says bool, initialized to null
/** @var array */
private $userMountingBackends = null; // @var says array, initialized to nullTyped property syntax is mixed with old docblock-only style. The 5.
6. Hardcoded blacklist in $blacklistedBackendsForUsers = ['\OC\Files\Storage\Local'];This in-method local variable carries no documentation. A short comment explaining why local storage is always blacklisted for users regardless of 7. Changelog grammar (also noted by @phil-davis)
SummaryThe security fix itself is sound and well-targeted. Main blockers before merge: (a) missing "allowed" happy-path test cases, (b) confirming the new controller tests actually exercise the intended code path, and (c) verifying the 422→403 change doesn't break frontend error handling. The type annotation issues, missing cache, and undocumented blacklist are minor but worth a cleanup pass. |
That's covered. The code checks for the visibility of the backend, and we have tests for both cases.
The controller will check for the backend visibility to allow or disallow the creation of the storage. The configuration check is deeper in the stack and it shouldn't matter for the unit tests because the controller doesn't depend directly on the
I'd rather keep the current 403 error because that's what happened before when the user tried to mount a local storage. We return the same error code, just from a different place. The rest of the topics are solved. Something to check is The isMountingUserAllowed is also checked during the validation for the StoragesBackendChecker, and it will cause the affected mounts to have the visibility reduced. We can remove that call and remove the config dependency from the controller. The behaviour will remain the same returning a 403 error code (if we keep the current error code in the validation)
|
This is done in the last commit |
Code ReviewOverviewThis PR fixes a security bypass where the local filesystem could be mounted as external storage by passing the internal PHP class name ( Code QualityPositive:
Minor style issues:
/** @var IConfig */
private IConfig $config;Same applies to
$blacklistedBackendsForUsers = ['\OC\Files\Storage\Local'];Prefer Potential Issues1. Fragile test reasoning in // there is already a teardown in the parent class setting this value to false
\OC::$server->getSystemConfig()->setValue('files_external_allow_create_new_local', false);
$result = $this->controller->create(...);
$this->assertEquals(Http::STATUS_FORBIDDEN, $result->getStatus());The 403 now comes from 2. Inconsistent
The different outcome based on the 3. Undocumented behavioral contract after removing runtime guards The PR removes all This is correct since SecurityThe core fix is correct. Moving the check from Summary
No blockers. The main suggestions are adding clarifying comments around the registration-time enforcement contract and the |
* fix: check for the identifier alias for the storage backend * test: add unit tests to local external storage * chore: add changelog entry * fix: move backend checks to a different place * fix: adjust unit tests * fix: visibility for local storage for the admin based on flag Without the visibility, the admin won't be able to create local storages, and the previously created local mounts will be hidden and inaccessible * fix: review comments * fix: remove user mounting check in controller and rely on validation * fix: adjust code based on reviews (cherry picked from commit 5c7dfc0) Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
* fix(security): OC10-75 - restrict AppConfigController read methods to full admins only (#41550) * fix(security): restrict AppConfigController read methods to full admins only OC10-75: Subadmins could read all oc_appconfig values including SMTP passwords and LDAP credentials via getApps/getKeys/getValue endpoints. Remove @NoAdminRequired so AdminMiddleware enforces full-admin-only access, consistent with the write methods. CVSS: 7.7 Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * fix: replace OC.AppConfig.getValue in users.js with server-rendered checkbox state The umgmt_set_password value is already rendered server-side into #CheckBoxPasswordOnUserCreate's checked attribute. Remove the redundant AJAX call which would now return 403 for Subadmins after the security fix. Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * chore: add changelog entry for OC10-75 (#41550) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> --------- Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(comments): prevent IDOR in WebDAV comments API (#41558) * test(comments): stub objectType/objectId in EntityCollection happy-path tests Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * test(comments): add failing IDOR regression tests for EntityCollection Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * fix(comments): prevent IDOR in WebDAV comments API by checking comment ownership An authenticated user could PROPFIND/DELETE/PROPPATCH any comment by supplying an arbitrary comment_id paired with any file_id they own. EntityCollection::getChild() and childExists() now verify that the fetched comment's objectType and objectId match the collection's own entity type and file ID before returning or confirming the node. Fixes OC10-53 Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * docs: add changelog entry for OC10-53 IDOR fix in WebDAV comments API Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> --------- Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(security): update phpseclib/phpseclib to 3.0.52 for CVE-2026-40194 CVE-2026-40194: timing attack in SSH binary packet processing fixed in 3.0.51. Also picks up 3.0.52 correctness fixes (ASN.1 hardening, OpenSSL 3.2+ RSA compat). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * fix(security): update symfony/routing to 5.4.52 for CVE-2026-45065 CVE-2026-45065: UrlGenerator regex alternation anchoring bypass allowing off-site URL injection via route requirement validation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * fix: check for the identifier alias for the storage backend (#41538) * fix: check for the identifier alias for the storage backend * test: add unit tests to local external storage * chore: add changelog entry * fix: move backend checks to a different place * fix: adjust unit tests * fix: visibility for local storage for the admin based on flag Without the visibility, the admin won't be able to create local storages, and the previously created local mounts will be hidden and inaccessible * fix: review comments * fix: remove user mounting check in controller and rely on validation * fix: adjust code based on reviews (cherry picked from commit 5c7dfc0) Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * fix: use the right user id when changing the email (#41539) * fix: use the right user id when changing the email * test: adjust unit test to ensure the mail is set for the user2 Previously, the test only used one user, so it was difficult to verify that the mail was changed for the user2 instead of user1 * docs: add changelog entry for PR #41539 * fix: include test to ensure the mail of the caller isn't changed --------- Co-authored-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> (cherry picked from commit 3ff2884) Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * chore: add changelog for 10.16.3 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> * ci: fix lint pipeline and sync with master * chore: set version properly and generate changelog Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> --------- Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Juan Pablo Villafañez <jpvillafanez@izertis.com>
Description
Prevent local storage to be used as external if it isn't explicitly allowed.
Related Issue
Motivation and Context
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist:
Notes:
This is likely the minimum change possible at the moment. There are no plans to add or modify the backend's aliases
or identifiers at the moment, but it could become unmanageable quickly.
We should consider to move and improve the check at some point.