Skip to content

fix(security): OC10-75 - restrict AppConfigController read methods to full admins only#41550

Merged
DeepDiver1975 merged 3 commits into
masterfrom
fix/oc10-75-appconfig-subadmin-privilege-escalation
May 21, 2026
Merged

fix(security): OC10-75 - restrict AppConfigController read methods to full admins only#41550
DeepDiver1975 merged 3 commits into
masterfrom
fix/oc10-75-appconfig-subadmin-privilege-escalation

Conversation

@DeepDiver1975

Copy link
Copy Markdown
Member

Summary

  • Security fix (CVSS 7.7): Removes @NoAdminRequired from getApps(), getKeys(), and getValue() in AppConfigController so the AppFramework's AdminMiddleware blocks Subadmin users from reading all oc_appconfig values (SMTP passwords, LDAP bind credentials, encryption master keys, etc.)
  • Collateral fix: Replaces a now-blocked OC.AppConfig.getValue AJAX call in settings/js/users/users.js with a synchronous DOM read of the server-rendered checkbox state — preserving correct UI behavior on the Subadmin-accessible /settings/users page
  • Updated the AppConfigController class docblock to accurately reflect that all methods now require full admin privileges

Details

The three read endpoints were annotated with @NoAdminRequired, which caused SecurityMiddleware to skip the admin check. Subadmins could exploit this to enumerate all app config keys and read any value — including credentials stored by SMTP, LDAP, OAuth, and encryption apps.

Write methods (setValue, deleteKey, deleteApp) were already admin-only. This PR makes the read methods consistent with them.

A cross-repo search of the entire ownCloud GitHub org found no other apps using the affected endpoints from Subadmin accessible UI, with one exception fixed here.

Reported by Pablo Giovanni. Confirmed on ownCloud 10.14.0 and 10.16.1.

Fixes: OC10-75

Test Plan

  • Log in as Subadmin → GET /index.php/settings/appconfig → HTTP 403
  • Log in as full admin → GET /index.php/settings/appconfig → HTTP 200
  • Log in as Subadmin → /settings/users → password/email field toggles correctly on page load
  • Log in as full admin → /settings/users → same behavior

…ns 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>
…heckbox 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>
@DeepDiver1975 DeepDiver1975 requested a review from jvillafanez May 18, 2026 21:29
@update-docs

update-docs Bot commented May 18, 2026

Copy link
Copy Markdown

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 DeepDiver1975 force-pushed the fix/oc10-75-appconfig-subadmin-privilege-escalation branch from 288cb95 to d00ecca Compare May 18, 2026 22:40

@jvillafanez jvillafanez left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We need to check how subadmins are impacted in the web UI. There might be broken operations.

@DeepDiver1975

Copy link
Copy Markdown
Member Author

We need to check how subadmins are impacted in the web UI. There might be broken operations.

Based on the analysis on where these endpoints are called - only users.js was affected.

But please feel free to test this as well - an additional pair of eyes is much appreciated 🙏

@jvillafanez

Copy link
Copy Markdown
Member
Screenshot from 2026-05-19 15-16-17

The checkboxes of the settings (bottom left corner) behaves weirdly for subadmins. The request returns with a 403, but both the checkbox and the affected field act as if it was successful. Of course, the settings aren't saved, so reloading the page will revert the page back.

Side note, the subdamin can't change the groups of the users he's managing. There have been changes in that regard, so I'm not sure about the correct state. It could be an expected behavior.

@DeepDiver1975

Copy link
Copy Markdown
Member Author

The checkboxes of the settings (bottom left corner) behaves weirdly for subadmins. The request returns with a 403, but both the checkbox and the affected field act as if it was successful. Of course, the settings aren't saved, so reloading the page will revert the page back.

I guess not saving the state is acceptable as side effect of this sec fix. The UI behaves correct ...

@DeepDiver1975

Copy link
Copy Markdown
Member Author

Side note, the subdamin can't change the groups of the users he's managing. There have been changes in that regard, so I'm not sure about the correct state. It could be an expected behavior.

no idea when (if?) this changed - never really using subadmin ....

@jvillafanez

Copy link
Copy Markdown
Member

Side note, the subdamin can't change the groups of the users he's managing. There have been changes in that regard, so I'm not sure about the correct state. It could be an expected behavior.

This seems to be expected (https://github.com/owncloud/core/blob/master/settings/js/users/users.js#L433-L438). Basically, for the subdamin, we require the users to be part of a group controlled by the subadmin. If there is only one group, it won't be possible to remove the user from that group, but if there are multiple groups the subadmin can move the users around those groups.
It seems to be a client-only check. The server allows removing the user. from the group.
It might be better to show the group as disabled if we can't interact with it, but I guess it's out of the scope at the moment.

DeepDiver1975 added a commit that referenced this pull request May 21, 2026
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
@DeepDiver1975 DeepDiver1975 force-pushed the fix/oc10-75-appconfig-subadmin-privilege-escalation branch from 494d0a6 to 6b5d8f3 Compare May 21, 2026 08:08
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
@DeepDiver1975 DeepDiver1975 force-pushed the fix/oc10-75-appconfig-subadmin-privilege-escalation branch from 6b5d8f3 to 7090534 Compare May 21, 2026 09:16
@DeepDiver1975 DeepDiver1975 merged commit da002b4 into master May 21, 2026
12 checks passed
@DeepDiver1975 DeepDiver1975 deleted the fix/oc10-75-appconfig-subadmin-privilege-escalation branch May 21, 2026 10:20
DeepDiver1975 added a commit that referenced this pull request May 21, 2026
… 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>
DeepDiver1975 added a commit that referenced this pull request Jun 1, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants