Skip to content

Commit c34a5d2

Browse files
nickvergessenbackportbot[bot]
authored andcommitted
fix(usermanager): Don't throw when checking if a too long user id is an existing user
Signed-off-by: Joas Schilling <coding@schilljs.com>
1 parent e51e64e commit c34a5d2

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

lib/private/User/DisplayNameCache.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
* @template-implements IEventListener<UserChangedEvent|UserDeletedEvent>
2525
*/
2626
class DisplayNameCache implements IEventListener {
27+
/** @see \OC\Config\UserConfig::USER_MAX_LENGTH */
28+
public const MAX_USERID_LENGTH = 64;
2729
private array $cache = [];
2830
private ICache $memCache;
2931
private IUserManager $userManager;
@@ -37,6 +39,11 @@ public function getDisplayName(string $userId): ?string {
3739
if (isset($this->cache[$userId])) {
3840
return $this->cache[$userId];
3941
}
42+
43+
if (strlen($userId) > self::MAX_USERID_LENGTH) {
44+
return null;
45+
}
46+
4047
$displayName = $this->memCache->get($userId);
4148
if ($displayName) {
4249
$this->cache[$userId] = $displayName;

lib/private/User/Manager.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
* @package OC\User
5454
*/
5555
class Manager extends PublicEmitter implements IUserManager {
56+
/** @see \OC\Config\UserConfig::USER_MAX_LENGTH */
57+
public const MAX_USERID_LENGTH = 64;
58+
5659
/**
5760
* @var \OCP\UserInterface[] $backends
5861
*/
@@ -131,6 +134,10 @@ public function get($uid) {
131134
return $this->cachedUsers[$uid];
132135
}
133136

137+
if (strlen($uid) > self::MAX_USERID_LENGTH) {
138+
return null;
139+
}
140+
134141
$cachedBackend = $this->cache->get(sha1($uid));
135142
if ($cachedBackend !== null && isset($this->backends[$cachedBackend])) {
136143
// Cache has the info of the user backend already, so ask that one directly
@@ -190,6 +197,10 @@ public function getUserObject($uid, $backend, $cacheUser = true) {
190197
* @return bool
191198
*/
192199
public function userExists($uid) {
200+
if (strlen($uid) > self::MAX_USERID_LENGTH) {
201+
return false;
202+
}
203+
193204
$user = $this->get($uid);
194205
return ($user !== null);
195206
}
@@ -705,14 +716,14 @@ public function getByEmail($email) {
705716
public function validateUserId(string $uid, bool $checkDataDirectory = false): void {
706717
$l = Server::get(IFactory::class)->get('lib');
707718

708-
// Check the name for bad characters
719+
// Check the ID for bad characters
709720
// Allowed are: "a-z", "A-Z", "0-9", spaces and "_.@-'"
710721
if (preg_match('/[^a-zA-Z0-9 _.@\-\']/', $uid)) {
711722
throw new \InvalidArgumentException($l->t('Only the following characters are allowed in an Login:'
712723
. ' "a-z", "A-Z", "0-9", spaces and "_.@-\'"'));
713724
}
714725

715-
// No empty username
726+
// No empty user ID
716727
if (trim($uid) === '') {
717728
throw new \InvalidArgumentException($l->t('A valid Login must be provided'));
718729
}
@@ -722,11 +733,16 @@ public function validateUserId(string $uid, bool $checkDataDirectory = false): v
722733
throw new \InvalidArgumentException($l->t('Login contains whitespace at the beginning or at the end'));
723734
}
724735

725-
// Username only consists of 1 or 2 dots (directory traversal)
736+
// User ID only consists of 1 or 2 dots (directory traversal)
726737
if ($uid === '.' || $uid === '..') {
727738
throw new \InvalidArgumentException($l->t('Login must not consist of dots only'));
728739
}
729740

741+
// User ID is too long
742+
if (strlen($uid) > self::MAX_USERID_LENGTH) {
743+
throw new \InvalidArgumentException($l->t('Login is too long'));
744+
}
745+
730746
if (!$this->verifyUid($uid, $checkDataDirectory)) {
731747
throw new \InvalidArgumentException($l->t('Login is invalid because files already exist for this user'));
732748
}

tests/lib/User/ManagerTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ public function testUserExistsSingleBackendExists(): void {
7979
$this->assertTrue($manager->userExists('foo'));
8080
}
8181

82+
public function testUserExistsTooLong(): void {
83+
/** @var \Test\Util\User\Dummy|MockObject $backend */
84+
$backend = $this->createMock(\Test\Util\User\Dummy::class);
85+
$backend->expects($this->never())
86+
->method('userExists')
87+
->with($this->equalTo('foo'))
88+
->willReturn(true);
89+
90+
$manager = new \OC\User\Manager($this->config, $this->cacheFactory, $this->eventDispatcher, $this->logger);
91+
$manager->registerBackend($backend);
92+
93+
$this->assertFalse($manager->userExists('foo' . str_repeat('a', 62)));
94+
}
95+
8296
public function testUserExistsSingleBackendNotExists(): void {
8397
/**
8498
* @var \Test\Util\User\Dummy | \PHPUnit\Framework\MockObject\MockObject $backend
@@ -230,6 +244,20 @@ public function testGetOneBackendNotExists(): void {
230244
$this->assertEquals(null, $manager->get('foo'));
231245
}
232246

247+
public function testGetTooLong(): void {
248+
/** @var \Test\Util\User\Dummy|MockObject $backend */
249+
$backend = $this->createMock(\Test\Util\User\Dummy::class);
250+
$backend->expects($this->never())
251+
->method('userExists')
252+
->with($this->equalTo('foo'))
253+
->willReturn(false);
254+
255+
$manager = new \OC\User\Manager($this->config, $this->cacheFactory, $this->eventDispatcher, $this->logger);
256+
$manager->registerBackend($backend);
257+
258+
$this->assertEquals(null, $manager->get('foo' . str_repeat('a', 62)));
259+
}
260+
233261
public function testGetOneBackendDoNotTranslateLoginNames(): void {
234262
/**
235263
* @var \Test\Util\User\Dummy | \PHPUnit\Framework\MockObject\MockObject $backend
@@ -333,6 +361,7 @@ public function dataCreateUserInvalid() {
333361
['..', 'foo', 'Username must not consist of dots only'],
334362
['.test', '', 'A valid password must be provided'],
335363
['test', '', 'A valid password must be provided'],
364+
['test' . str_repeat('a', 61), '', 'Login is too long'],
336365
];
337366
}
338367

0 commit comments

Comments
 (0)