Skip to content

fix(files_sharing): enforce minimum search length in getUsers() and getGroups()#41580

Open
DeepDiver1975 wants to merge 3 commits into
masterfrom
security/fix-sharees-min-search-length
Open

fix(files_sharing): enforce minimum search length in getUsers() and getGroups()#41580
DeepDiver1975 wants to merge 3 commits into
masterfrom
security/fix-sharees-min-search-length

Conversation

@DeepDiver1975

Copy link
Copy Markdown
Member

Summary

  • getUsers() and getGroups() in ShareesController only blocked empty strings, not strings shorter than the admin-configured user.search_min_length
  • isSearchable() was already enforced in getRemote() but not in the other two search methods
  • Fix adds the missing isSearchable() guard, closing the bypass

Security Impact

Low — authenticated-only endpoint; bypass only relevant when admin raises min length above default

Test plan

  • New tests testGetUsersBlocksShortSearchTerm() and testGetGroupsBlocksShortSearchTerm() assert that backends are never queried when search term is below configured minimum
  • Run make test TEST_PHP_SUITE=apps/files_sharing

🤖 Generated with Claude Code

…etGroups()

The admin-configurable user.search_min_length was only enforced in
getRemote() via isSearchable() but not in getUsers() or getGroups().
A 1-character search bypassed the intended restriction and allowed
authenticated users to enumerate users even when a higher minimum
was configured. Add the missing isSearchable() guard to both methods.

Signed-off-by: Thomas Müller <thomas.mueller@owncloud.com>
Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
@update-docs

update-docs Bot commented Jun 5, 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.

Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
… setUp

Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>

@DeepDiver1975 DeepDiver1975 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Code Review — fix(files_sharing): enforce minimum search length in getUsers() and getGroups()

Overview: Adds the missing isSearchable() guard to getUsers() and getGroups() in ShareesController. The remote search path already had this guard; the user/group paths only blocked empty strings, allowing a single-character query to bypass the admin-configured minimum search length.

Correctness

The fix is minimal and consistent — four identical lines added symmetrically to both methods, mirroring the existing pattern in getRemote(). ✅

Test default in setUp(): The willReturn(true) default for isSearchable is the right call — it makes existing tests transparent to the new guard without requiring them all to be updated. New tests override this default. ✅

testGetUsersBlocksShortSearchTerm: Correctly asserts:

  • isSearchable('a') returns false
  • userManager->find() is never called
  • result users array is empty

testGetGroupsBlocksShortSearchTerm: Correctly asserts:

  • isSearchable('a') returns false
  • groupManager->search() is never called
  • result groups array is empty

One minor observation: Both new tests call $this->userSearch->expects($this->any())->method('getSearchMinLength'). isSearchable() is what the production code calls; getSearchMinLength isn't directly invoked by the patched code paths. This any() expectation is unreferenced and effectively dead — harmless but slightly confusing. Not blocking.

Changelog

The changelog entry in changelog/unreleased/41580 accurately describes the bypass and the fix. ✅

Summary

Aspect Assessment
Fix ✅ Consistent, minimal — mirrors existing getRemote() pattern
Tests ✅ Both new cases assert backend is never queried for short terms
Test default setUp() default willReturn(true) doesn't break existing tests
Changelog ✅ Accurate and clear

Verdict: Ready to merge.

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.

1 participant