Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix(theming): Harden admin web link settings
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux authored and backportbot[bot] committed Jan 27, 2025
commit a8c2769cae567b90fcafb65069419235d7603f1b
8 changes: 5 additions & 3 deletions apps/theming/lib/Controller/ThemingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,13 @@ public function updateAppMenu($setting, $value) {
}

/**
* Check that a string is a valid http/https url
* Check that a string is a valid http/https url.
* Also validates that there is no way for XSS through HTML
*/
private function isValidUrl(string $url): bool {
return ((str_starts_with($url, 'http://') || str_starts_with($url, 'https://')) &&
filter_var($url, FILTER_VALIDATE_URL) !== false);
return ((str_starts_with($url, 'http://') || str_starts_with($url, 'https://'))
&& filter_var($url, FILTER_VALIDATE_URL) !== false)
&& !str_contains($url, '"');
}

/**
Expand Down
25 changes: 18 additions & 7 deletions apps/theming/tests/Controller/ThemingControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,33 @@ public function testUpdateStylesheetSuccess($setting, $value, $message): void {
}

public function dataUpdateStylesheetError() {
$urls = [
'url' => 'web address',
'imprintUrl' => 'legal notice address',
'privacyUrl' => 'privacy policy address',
];

$urlTests = [];
foreach ($urls as $urlKey => $urlName) {
// Check length limit
$urlTests[] = [$urlKey, 'http://example.com/' . str_repeat('a', 501), "The given {$urlName} is too long"];
// Check potential evil javascript
$urlTests[] = [$urlKey, 'javascript:alert(1)', "The given {$urlName} is not a valid URL"];
// Check XSS
$urlTests[] = [$urlKey, 'https://example.com/"><script/src="alert(\'1\')"><a/href/="', "The given {$urlName} is not a valid URL"];
}

return [
['name', str_repeat('a', 251), 'The given name is too long'],
['url', 'http://example.com/' . str_repeat('a', 501), 'The given web address is too long'],
['url', str_repeat('a', 501), 'The given web address is not a valid URL'],
['url', 'javascript:alert(1)', 'The given web address is not a valid URL'],
['slogan', str_repeat('a', 501), 'The given slogan is too long'],
['primary_color', '0082C9', 'The given color is invalid'],
['primary_color', '#0082Z9', 'The given color is invalid'],
['primary_color', 'Nextcloud', 'The given color is invalid'],
['background_color', '0082C9', 'The given color is invalid'],
['background_color', '#0082Z9', 'The given color is invalid'],
['background_color', 'Nextcloud', 'The given color is invalid'],
['imprintUrl', '0082C9', 'The given legal notice address is not a valid URL'],
['imprintUrl', '0082C9', 'The given legal notice address is not a valid URL'],
['imprintUrl', 'javascript:foo', 'The given legal notice address is not a valid URL'],
['privacyUrl', '#0082Z9', 'The given privacy policy address is not a valid URL'],

...$urlTests,
];
}

Expand Down