diff --git a/src/snek/app.py b/src/snek/app.py index b4ddec9..d759536 100644 --- a/src/snek/app.py +++ b/src/snek/app.py @@ -62,6 +62,7 @@ from snek.webdav import WebdavApplication from snek.system.template import sanitize_html from snek.sgit import GitApplication SESSION_KEY = b"c79a0c5fda4b424189c427d28c9f7c34" +from snek.system.template import whitelist_attributes @web.middleware @@ -285,9 +286,9 @@ class Application(BaseApplication): async def handle_test(self, request): - return await self.render_template( + return await whitelist_attributes(self.render_template( "test.html", request, context={"name": "retoor"} - ) + )) async def handle_http_get(self, request: web.Request): url = request.query.get("url") @@ -358,7 +359,9 @@ class Application(BaseApplication): rendered = await super().render_template(template, request, context) self.jinja2_env.loader = self.original_loader - + + #rendered.text = whitelist_attributes(rendered.text) + #rendered.headers['Content-Lenght'] = len(rendered.text) return rendered diff --git a/src/snek/service/channel_message.py b/src/snek/service/channel_message.py index c512e21..0579451 100644 --- a/src/snek/service/channel_message.py +++ b/src/snek/service/channel_message.py @@ -1,4 +1,5 @@ from snek.system.service import BaseService +from snek.system.template import whitelist_attributes class ChannelMessageService(BaseService): @@ -28,6 +29,7 @@ class ChannelMessageService(BaseService): try: template = self.app.jinja2_env.get_template("message.html") model["html"] = template.render(**context) + model["html"] = whitelist_attributes(model["html"]) except Exception as ex: print(ex, flush=True) diff --git a/src/snek/system/template.py b/src/snek/system/template.py index 4c023a7..76af47f 100644 --- a/src/snek/system/template.py +++ b/src/snek/system/template.py @@ -118,7 +118,24 @@ def set_link_target_blank(text): element.attrs["rel"] = "noopener noreferrer" element.attrs["referrerpolicy"] = "no-referrer" element.attrs["href"] = element.attrs["href"].strip(".").strip(",") + + return str(soup) +SAFE_ATTRIBUTES = { + 'href', 'src', 'alt', 'title', 'width', 'height', 'style', 'id', 'class', + 'rel', 'type', 'name', 'value', 'placeholder', 'aria-hidden', 'aria-label', 'srcset' +} + +def whitelist_attributes(html): + soup = BeautifulSoup(html, 'html.parser') + + for tag in soup.find_all(): + if isinstance(tag, Tag): + attrs = dict(tag.attrs) + for attr in list(attrs): + # Check if attribute is in the safe list or is a data-* attribute + if not (attr in SAFE_ATTRIBUTES or attr.startswith('data-')): + del tag.attrs[attr] return str(soup)