Skip to content

Commit a8c2769

Browse files
susnuxbackportbot[bot]
authored andcommitted
fix(theming): Harden admin web link settings
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 7b3daaf commit a8c2769

2 files changed

Lines changed: 23 additions & 10 deletions

File tree

apps/theming/lib/Controller/ThemingController.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,13 @@ public function updateAppMenu($setting, $value) {
194194
}
195195

196196
/**
197-
* Check that a string is a valid http/https url
197+
* Check that a string is a valid http/https url.
198+
* Also validates that there is no way for XSS through HTML
198199
*/
199200
private function isValidUrl(string $url): bool {
200-
return ((str_starts_with($url, 'http://') || str_starts_with($url, 'https://')) &&
201-
filter_var($url, FILTER_VALIDATE_URL) !== false);
201+
return ((str_starts_with($url, 'http://') || str_starts_with($url, 'https://'))
202+
&& filter_var($url, FILTER_VALIDATE_URL) !== false)
203+
&& !str_contains($url, '"');
202204
}
203205

204206
/**

apps/theming/tests/Controller/ThemingControllerTest.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,22 +125,33 @@ public function testUpdateStylesheetSuccess($setting, $value, $message): void {
125125
}
126126

127127
public function dataUpdateStylesheetError() {
128+
$urls = [
129+
'url' => 'web address',
130+
'imprintUrl' => 'legal notice address',
131+
'privacyUrl' => 'privacy policy address',
132+
];
133+
134+
$urlTests = [];
135+
foreach ($urls as $urlKey => $urlName) {
136+
// Check length limit
137+
$urlTests[] = [$urlKey, 'http://example.com/' . str_repeat('a', 501), "The given {$urlName} is too long"];
138+
// Check potential evil javascript
139+
$urlTests[] = [$urlKey, 'javascript:alert(1)', "The given {$urlName} is not a valid URL"];
140+
// Check XSS
141+
$urlTests[] = [$urlKey, 'https://example.com/"><script/src="alert(\'1\')"><a/href/="', "The given {$urlName} is not a valid URL"];
142+
}
143+
128144
return [
129145
['name', str_repeat('a', 251), 'The given name is too long'],
130-
['url', 'http://example.com/' . str_repeat('a', 501), 'The given web address is too long'],
131-
['url', str_repeat('a', 501), 'The given web address is not a valid URL'],
132-
['url', 'javascript:alert(1)', 'The given web address is not a valid URL'],
133146
['slogan', str_repeat('a', 501), 'The given slogan is too long'],
134147
['primary_color', '0082C9', 'The given color is invalid'],
135148
['primary_color', '#0082Z9', 'The given color is invalid'],
136149
['primary_color', 'Nextcloud', 'The given color is invalid'],
137150
['background_color', '0082C9', 'The given color is invalid'],
138151
['background_color', '#0082Z9', 'The given color is invalid'],
139152
['background_color', 'Nextcloud', 'The given color is invalid'],
140-
['imprintUrl', '0082C9', 'The given legal notice address is not a valid URL'],
141-
['imprintUrl', '0082C9', 'The given legal notice address is not a valid URL'],
142-
['imprintUrl', 'javascript:foo', 'The given legal notice address is not a valid URL'],
143-
['privacyUrl', '#0082Z9', 'The given privacy policy address is not a valid URL'],
153+
154+
...$urlTests,
144155
];
145156
}
146157

0 commit comments

Comments
 (0)