From bd6115ad62bd8b8610f5bb23c92305c368e57d37 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Mon, 21 Mar 2016 01:15:46 -0500 Subject: [PATCH] fixed Host header vulnerability #1196 --- applications/welcome/models/db.py | 3 ++- applications/welcome/private/appconfig.ini | 2 +- gluon/contrib/appconfig.py | 4 ++-- gluon/tools.py | 23 ++++++++++++++++++++-- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/applications/welcome/models/db.py b/applications/welcome/models/db.py index 68660581..6e12479b 100644 --- a/applications/welcome/models/db.py +++ b/applications/welcome/models/db.py @@ -58,7 +58,8 @@ response.form_label_separator = myconf.get('forms.separator') or '' from gluon.tools import Auth, Service, PluginManager -auth = Auth(db, host=myconf.get('host.name')) +# host names must be a list of allowed host names (glob syntax allowed) +auth = Auth(db, host_names=myconf.get('host.names')) service = Service() plugins = PluginManager() diff --git a/applications/welcome/private/appconfig.ini b/applications/welcome/private/appconfig.ini index bf7412b9..f0813547 100644 --- a/applications/welcome/private/appconfig.ini +++ b/applications/welcome/private/appconfig.ini @@ -8,7 +8,7 @@ generator = Web2py Web Framework ; Host configuration [host] -name = localhost +names = localhost:*, 127.0.0.1:*, *:*, * ; db configuration [db] diff --git a/gluon/contrib/appconfig.py b/gluon/contrib/appconfig.py index 5bbd4829..af6279c0 100644 --- a/gluon/contrib/appconfig.py +++ b/gluon/contrib/appconfig.py @@ -69,8 +69,8 @@ class AppConfigDict(dict): return False elif value.isdigit() or (value[0]=='-' and value[1:].isdigit()): return int(value) - elif ', ' in value: - return value.split(', ') + elif ',' in value: + return map(lambda x:x.strip(),value.split(',')) else: try: return float(value) diff --git a/gluon/tools.py b/gluon/tools.py index 6e5b2f4f..fbebcc00 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -23,6 +23,7 @@ import glob import os import re import time +import fnmatch import traceback import smtplib import urllib @@ -1717,11 +1718,29 @@ class Auth(object): def here(self): return URL(args=current.request.args, vars=current.request.get_vars) + def select_host(self, host, host_names=None): + """ + checks that host is valid, i.e. in the list of glob host_names + if the host is missing, then is it selects the first entry from host_names + read more here: https://github.com/web2py/web2py/issues/1196 + """ + if host: + if host_names: + for item in host_names: + if fnmatch.fnmatch(host, item): + break + else: + raise HTTP(403, "Invalid Hostname") + elif host_names: + host = host_names[0] + else: + host = 'localhost' + def __init__(self, environment=None, db=None, mailer=True, hmac_key=None, controller='default', function='user', cas_provider=None, signature=True, secure=False, csrf_prevention=True, propagate_extension=None, - url_index=None, jwt=None, host=None): + url_index=None, jwt=None, host_names=None): ## next two lines for backward compatibility if not db and environment and isinstance(environment, DAL): @@ -1765,7 +1784,7 @@ class Auth(object): settings = self.settings = Settings() settings.update(Auth.default_settings) - host = host or request.env.http_host + host = self.select_host(request.env.http_host, host_names) settings.update( cas_domains=[host], enable_tokens=False,