From 548f976d35fd9831420bb884b9dee04ec28d7047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Tue, 6 Oct 2015 13:41:54 +0200 Subject: [PATCH] Some more defensive escaping for various settings in the UI Entering HTML fragments into the webcam stream URL could cause issues, anything injected via Jinja should now be escaped properly. --- src/octoprint/server/views.py | 9 +++++++++ src/octoprint/templates/dialogs/settings.jinja2 | 2 +- .../templates/dialogs/usersettings.jinja2 | 2 +- src/octoprint/templates/index.jinja2 | 6 +++--- src/octoprint/templates/initscript.jinja2 | 16 ++++++++-------- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/octoprint/server/views.py b/src/octoprint/server/views.py index 905e1436..f89bd9da 100644 --- a/src/octoprint/server/views.py +++ b/src/octoprint/server/views.py @@ -16,11 +16,16 @@ from octoprint.server import app, userManager, pluginManager, gettext, \ debug, LOCALES, VERSION, DISPLAY_VERSION, UI_API_KEY, BRANCH from octoprint.settings import settings +import re + from . import util import logging _logger = logging.getLogger(__name__) +_valid_id_re = re.compile("[a-z_]+") +_valid_div_re = re.compile("[a-zA-Z_-]+") + @app.route("/") @util.flask.cached(refreshif=lambda: util.flask.cache_check_headers() or "_refresh" in request.values, key=lambda: "view/%s/%s" % (request.path, g.locale), @@ -367,6 +372,9 @@ def _process_template_config(name, implementation, rule, config=None, counter=1) data["_div"] = rule["div"](name) if "suffix" in data: data["_div"] = data["_div"] + data["suffix"] + if not _valid_div_re.match(data["_div"]): + _logger.warn("Template config {} contains invalid div identifier {}, skipping it".format(name, data["_div"])) + return None if not "template" in data: data["template"] = rule["template"](name) @@ -378,6 +386,7 @@ def _process_template_config(name, implementation, rule, config=None, counter=1) data_bind = "allowBindings: true" if "data_bind" in data: data_bind = data_bind + ", " + data["data_bind"] + data_bind = data_bind.replace("\"", "\\\"") data["data_bind"] = data_bind data["_key"] = "plugin_" + name diff --git a/src/octoprint/templates/dialogs/settings.jinja2 b/src/octoprint/templates/dialogs/settings.jinja2 index f3d3f708..a87fa6a6 100644 --- a/src/octoprint/templates/dialogs/settings.jinja2 +++ b/src/octoprint/templates/dialogs/settings.jinja2 @@ -20,7 +20,7 @@ class="{% if mark_active %}active{% set mark_active = False %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" {% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %} > - {{ entry }} + {{ entry|e }} {% if "custom_bindings" not in data or data["custom_bindings"] %}{% endif %} {% endif %} diff --git a/src/octoprint/templates/dialogs/usersettings.jinja2 b/src/octoprint/templates/dialogs/usersettings.jinja2 index 00cbcc6c..be405c15 100644 --- a/src/octoprint/templates/dialogs/usersettings.jinja2 +++ b/src/octoprint/templates/dialogs/usersettings.jinja2 @@ -17,7 +17,7 @@ class="{% if mark_active %}active{% set mark_active = False %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" {% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %} > - {{ entry }} + {{ entry|e }} {% if "custom_bindings" not in data or data["custom_bindings"] %}{% endif %} {% endif %} diff --git a/src/octoprint/templates/index.jinja2 b/src/octoprint/templates/index.jinja2 index 1a58a82b..a5de49c1 100644 --- a/src/octoprint/templates/index.jinja2 +++ b/src/octoprint/templates/index.jinja2 @@ -55,7 +55,7 @@ >
- {% if "icon" in data %} {% endif %}{{ entry }} + {% if "icon" in data %} {% endif %}{{ entry|e }} {% if "template_header" in data %} {% include data.template_header ignore missing %} @@ -87,7 +87,7 @@ {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} {% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %} > - {{ entry }} + {{ entry|e }} {% if "custom_bindings" not in data or data["custom_bindings"] %}{% endif %} {% endfor %} @@ -112,7 +112,7 @@