diff --git a/deluge/ui/webui/config_forms.py b/deluge/ui/webui/config_forms.py index 4eaceb9da..455c500ea 100644 --- a/deluge/ui/webui/config_forms.py +++ b/deluge/ui/webui/config_forms.py @@ -53,6 +53,7 @@ class WebCfgForm(forms.Form): return config.get_config() def save(self, data): + utils.validate_config(data) for key, value in data.iteritems(): config.set(key, value) config.save() diff --git a/deluge/ui/webui/config_tabs_webui.py b/deluge/ui/webui/config_tabs_webui.py index 5c481d2a5..bcf8f180e 100644 --- a/deluge/ui/webui/config_tabs_webui.py +++ b/deluge/ui/webui/config_tabs_webui.py @@ -43,6 +43,7 @@ from render import render config_page = component.get("ConfigPageManager") plugins = component.get("WebPluginManager") + class Template(config_forms.WebCfgForm): title = _("Template") diff --git a/deluge/ui/webui/pages.py b/deluge/ui/webui/pages.py index 906b71f2c..aaff59de4 100644 --- a/deluge/ui/webui/pages.py +++ b/deluge/ui/webui/pages.py @@ -394,8 +394,14 @@ class template_render: "render anything in /render/ dir" @deco.deluge_page def GET(self, name): - filename = os.path.join(os.path.dirname(__file__), - 'templates/%s/render/%s' % (config.get('template'), name)) + #security : assumes config.get('template') returns a safe subdir. + basepath = os.path.normpath(os.path.join(os.path.dirname(__file__), + 'templates/%s/render' % config.get('template'))) + filename = os.path.normpath(os.path.join(basepath,name)) + if not filename.startswith(basepath): + #hack detected? + raise Exception("File to render is not located in %s" % basepath) + return web.template.Template(open(filename).read(), filename=filename)() route("/template/render/(.*)", template_render) diff --git a/deluge/ui/webui/utils.py b/deluge/ui/webui/utils.py index 71bd3bff1..610c8a52d 100644 --- a/deluge/ui/webui/utils.py +++ b/deluge/ui/webui/utils.py @@ -250,6 +250,18 @@ def check_pwd(pwd): m.update(pwd) return (m.digest() == config.get('pwd_md5')) +def validate_config(cfg_dict): + """ + call this before setting webui-config! + #security : if template contains "../.." or other vars the filesystem could get compromized. + """ + if "template" in cfg_dict: + from render import render + #make shure it is a real template + if not cfg_dict["template"] in render.get_templates(): + raise Exception("Invalid template") + + def set_config_defaults(): changed = False for key, value in CONFIG_DEFAULTS.iteritems():