mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
fix(appsettings): the theme must be one of the themes in SASS_DIR
The settings page took the posted theme name as it came and wrote it into the @import lines of wvc-main.scss and the compiled CSS: a name with "../" or a quote imported files outside the themes directory (CodeQL py/path-injection; the page is for superusers). The name must now be one of the directories in SASS_DIR/wvc-themes, the list the page already offers; anything else is refused with a message and nothing is written. themes_list is empty when SASS_DIR has no themes, so every name is refused then. Checked with the real dev/scss: flatly is applied and compiled as before, "../../etc" is refused and leaves the CSS alone. The test fails on the previous code.
This commit is contained in:
parent
8383a07ae3
commit
d816d8d09f
2 changed files with 32 additions and 0 deletions
27
appsettings/test_theme_name.py
Normal file
27
appsettings/test_theme_name.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
"""The theme name posted on the settings page must be one of the themes in
|
||||
SASS_DIR/wvc-themes: it is written into @import paths and the compiled CSS."""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from appsettings.models import AppSettings
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
class ThemeNameTests(TestCase):
|
||||
def setUp(self):
|
||||
self.client.force_login(User.objects.create_superuser("th-admin", "th@example.com", "pw"))
|
||||
self.sass = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.sass.cleanup)
|
||||
os.makedirs(os.path.join(self.sass.name, "wvc-themes", "flatly"))
|
||||
AppSettings.objects.filter(key="SASS_DIR").update(value=self.sass.name)
|
||||
self.before = AppSettings.objects.get(key="BOOTSTRAP_THEME").value
|
||||
|
||||
def test_a_name_that_is_not_a_theme_is_refused(self):
|
||||
for theme in ("../../etc", "flatly';@import '/etc/passwd", "nope", ""):
|
||||
with self.subTest(theme=theme):
|
||||
self.client.post(reverse("appsettings"), {"BOOTSTRAP_THEME": theme})
|
||||
self.assertFalse(os.path.exists(os.path.join(self.sass.name, "wvc-main.scss")))
|
||||
self.assertEqual(AppSettings.objects.get(key="BOOTSTRAP_THEME").value, self.before)
|
||||
|
|
@ -20,6 +20,7 @@ def appsettings(request):
|
|||
main_css = "wvc-main.min.css"
|
||||
sass_dir = AppSettings.objects.get(key="SASS_DIR")
|
||||
bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
|
||||
themes_list = []
|
||||
try:
|
||||
themes_list = os.listdir(sass_dir.value + "/wvc-themes")
|
||||
except FileNotFoundError as err:
|
||||
|
|
@ -50,6 +51,10 @@ def appsettings(request):
|
|||
|
||||
if "BOOTSTRAP_THEME" in request.POST:
|
||||
theme = request.POST.get("BOOTSTRAP_THEME", "")
|
||||
# the name goes into @import paths: only the themes in SASS_DIR
|
||||
if theme not in themes_list:
|
||||
messages.error(request, _("Unknown theme: %(theme)s") % {"theme": theme})
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
scss_var = f"@import '{sass_dir.value}/wvc-themes/{theme}/variables';"
|
||||
# scss_boot = f"@import '{sass_dir.value}/bootstrap/bootstrap.scss';"
|
||||
scss_boot = f"@import '{sass_dir.value}/bootstrap-overrides.scss';"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue