From f12b52165a26a37e1ad1da970cf3dffc0d2b8de8 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 15 Nov 2020 09:55:49 +0000 Subject: [PATCH 01/44] Themes can contain custom fonts --- theme.py | 60 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/theme.py b/theme.py index 8492060ac..d04b0f571 100644 --- a/theme.py +++ b/theme.py @@ -27,7 +27,8 @@ def getThemesList(baseDir: str) -> []: themes = [] for subdir, dirs, files in os.walk(baseDir + '/theme'): for themeName in dirs: - if '~' not in themeName and themeName != 'icons': + if '~' not in themeName and \ + themeName != 'icons' and themeName != 'fonts': themes.append(themeName.title()) break print('Themes available: ' + str(themes)) @@ -411,34 +412,46 @@ def setThemeHighVis(baseDir: str): setThemeFromDict(baseDir, name, themeParams, bgParams) +def setThemeFonts(baseDir: str, themeName: str) -> None: + """Adds custom theme fonts + """ + themeNameLower = themeName.lower() + fontsDir = baseDir + '/fonts' + themeFontsDir = \ + baseDir + '/theme/' + themeNameLower + '/fonts' + if not os.path.isdir(themeFontsDir): + return + for subdir, dirs, files in os.walk(themeFontsDir): + for filename in files: + if filename.endswith('.woff2') or \ + filename.endswith('.woff') or \ + filename.endswith('.ttf') or \ + filename.endswith('.otf'): + destFilename = fontsDir + '/' + filename + if os.path.isfile(destFilename): + # font already exists in the destination location + continue + copyfile(themeFontsDir + '/' + filename, + destFilename) + break + + def setThemeImages(baseDir: str, name: str) -> None: """Changes the profile background image and banner to the defaults """ themeNameLower = name.lower() - if themeNameLower == 'default': - profileImageFilename = \ - baseDir + '/theme/default/image.png' - bannerFilename = \ - baseDir + '/theme/default/banner.png' - searchBannerFilename = \ - baseDir + '/theme/default/search_banner.png' - leftColImageFilename = \ - baseDir + '/theme/default/left_col_image.png' - rightColImageFilename = \ - baseDir + '/theme/default/right_col_image.png' - else: - profileImageFilename = \ - baseDir + '/theme/' + themeNameLower + '/image.png' - bannerFilename = \ - baseDir + '/theme/' + themeNameLower + '/banner.png' - searchBannerFilename = \ - baseDir + '/theme/' + themeNameLower + '/search_banner.png' - leftColImageFilename = \ - baseDir + '/theme/' + themeNameLower + '/left_col_image.png' - rightColImageFilename = \ - baseDir + '/theme/' + themeNameLower + '/right_col_image.png' + profileImageFilename = \ + baseDir + '/theme/' + themeNameLower + '/image.png' + bannerFilename = \ + baseDir + '/theme/' + themeNameLower + '/banner.png' + searchBannerFilename = \ + baseDir + '/theme/' + themeNameLower + '/search_banner.png' + leftColImageFilename = \ + baseDir + '/theme/' + themeNameLower + '/left_col_image.png' + rightColImageFilename = \ + baseDir + '/theme/' + themeNameLower + '/right_col_image.png' backgroundNames = ('login', 'shares', 'delete', 'follow', 'options', 'block', 'search', 'calendar') @@ -572,6 +585,7 @@ def setTheme(baseDir: str, name: str, domain: str) -> bool: # change the banner and profile image # to the default for the theme setThemeImages(baseDir, name) + setThemeFonts(baseDir, name) result = True if not result: From a7972ffba0aa283b1b84cb10d1cd4f4eea96487c Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 15 Nov 2020 10:33:11 +0000 Subject: [PATCH 02/44] Check for dangerous css --- theme.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/theme.py b/theme.py index d04b0f571..b62ed54bc 100644 --- a/theme.py +++ b/theme.py @@ -12,6 +12,23 @@ from utils import saveJson from shutil import copyfile +def dangerousCSS(filename: str) -> bool: + """Returns true is the css file contains code which + can create security problems + """ + if not os.path.isfile(filename): + return False + + with open(filename, 'r') as fp: + css = fp.read() + + cssMatches = ('behavior') + for match in cssMatches: + if match in css: + return True + return False + + def getThemeFiles() -> []: return ('epicyon.css', 'login.css', 'follow.css', 'suspended.css', 'calendar.css', 'blog.css', @@ -186,7 +203,8 @@ def setThemeFromDict(baseDir: str, name: str, templateFilename = \ baseDir + '/theme/' + name + '/epicyon-profile.css' - if not os.path.isfile(templateFilename): + if dangerousCSS(templateFilename) or \ + not os.path.isfile(templateFilename): # use default css templateFilename = baseDir + '/epicyon-' + filename if filename == 'epicyon.css': From 1f1cbd3eea0f3d36c5ceba3642a09fbf85884514 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 15 Nov 2020 10:36:24 +0000 Subject: [PATCH 03/44] Another script test --- tests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests.py b/tests.py index 0431387a0..893fc036d 100644 --- a/tests.py +++ b/tests.py @@ -1952,6 +1952,11 @@ def testDangerousMarkup(): '.innerHTML = "evil";

' assert(dangerousMarkup(content)) + content = '

This html contains more than you expected... ' + \ + '

' + assert(dangerousMarkup(content)) + content = '

This is a valid-looking message. But wait... ' + \ '