Skip to content

Commit f1f67f4

Browse files
committed
fix(federation): Allow outgoing federation with oCIS federated cloud ids
Signed-off-by: Joas Schilling <coding@schilljs.com>
1 parent 4c17229 commit f1f67f4

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

lib/private/Federation/CloudIdManager.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public function resolveCloudId(string $cloudId): ICloudId {
108108
// We accept slightly more chars when working with federationId than with a local userId.
109109
// We remove those eventual chars from the UserId before using
110110
// the IUserManager API to confirm its format.
111-
$this->userManager->validateUserId(str_replace('=', '-', $user));
111+
$this->validateUser($user, $remote);
112112

113113
if (!empty($user) && !empty($remote)) {
114114
$remote = $this->ensureDefaultProtocol($remote);
@@ -118,6 +118,36 @@ public function resolveCloudId(string $cloudId): ICloudId {
118118
throw new \InvalidArgumentException('Invalid cloud id');
119119
}
120120

121+
protected function validateUser(string $user, string $remote): void {
122+
// Check the ID for bad characters
123+
// Allowed are: "a-z", "A-Z", "0-9", spaces and "_.@-'" (Nextcloud)
124+
// Additional: "=" (oCIS)
125+
if (preg_match('/[^a-zA-Z0-9 _.@\-\'=]/', $user)) {
126+
throw new \InvalidArgumentException('Invalid characters');
127+
}
128+
129+
// No empty user ID
130+
if (trim($user) === '') {
131+
throw new \InvalidArgumentException('Empty user');
132+
}
133+
134+
// No whitespace at the beginning or at the end
135+
if (trim($user) !== $user) {
136+
throw new \InvalidArgumentException('User contains whitespace at the beginning or at the end');
137+
}
138+
139+
// User ID only consists of 1 or 2 dots (directory traversal)
140+
if ($user === '.' || $user === '..') {
141+
throw new \InvalidArgumentException('User must not consist of dots only');
142+
}
143+
144+
// User ID is too long
145+
if (strlen($user . '@' . $remote) > 255) {
146+
// TRANSLATORS User ID is too long
147+
throw new \InvalidArgumentException('Cloud id is too long');
148+
}
149+
}
150+
121151
public function getDisplayNameFromContact(string $cloudId): ?string {
122152
$cachedName = $this->displayNameCache->get($cloudId);
123153
if ($cachedName !== null) {

0 commit comments

Comments
 (0)