misc: limit cancel URL to relatable URLs (#43276)
This commit is contained in:
parent
05c1573e38
commit
c3795921c3
|
@ -428,6 +428,47 @@ def test_form_access_auth_context(pub):
|
|||
assert resp.form
|
||||
|
||||
|
||||
def test_form_cancelurl(pub):
|
||||
formdef = create_formdef()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
# path
|
||||
resp = get_app(pub).get('/test/?cancelurl=/plop/')
|
||||
resp = resp.form.submit('cancel')
|
||||
assert resp.location == 'http://example.net/plop/'
|
||||
|
||||
# full URL
|
||||
resp = get_app(pub).get('/test/?cancelurl=http://example.net/plop/')
|
||||
resp = resp.form.submit('cancel')
|
||||
assert resp.location == 'http://example.net/plop/'
|
||||
|
||||
# remote site
|
||||
get_app(pub).get('/test/?cancelurl=http://example.org/plop/', status=400)
|
||||
|
||||
pub.site_options.add_section('api-secrets')
|
||||
pub.site_options.set('api-secrets', 'example.org', 'xyz')
|
||||
pub.site_options.write(open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w'))
|
||||
resp = get_app(pub).get('/test/?cancelurl=http://example.org/plop/')
|
||||
resp = resp.form.submit('cancel')
|
||||
assert resp.location == 'http://example.org/plop/'
|
||||
|
||||
pub.site_options.remove_section('api-secrets')
|
||||
if not pub.site_options.has_section('options'):
|
||||
pub.site_options.add_section('options')
|
||||
pub.site_options.write(open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w'))
|
||||
get_app(pub).get('/test/?cancelurl=http://example.org/plop/', status=400)
|
||||
|
||||
pub.site_options.set('options', 'relatable-hosts', 'example.com')
|
||||
pub.site_options.write(open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w'))
|
||||
get_app(pub).get('/test/?cancelurl=http://example.org/plop/', status=400)
|
||||
|
||||
pub.site_options.set('options', 'relatable-hosts', 'example.com, example.org')
|
||||
pub.site_options.write(open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w'))
|
||||
resp = get_app(pub).get('/test/?cancelurl=http://example.org/plop/')
|
||||
resp = resp.form.submit('cancel')
|
||||
assert resp.location == 'http://example.org/plop/'
|
||||
|
||||
|
||||
def test_form_submit(pub):
|
||||
formdef = create_formdef()
|
||||
formdef.data_class().wipe()
|
||||
|
|
|
@ -328,6 +328,8 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
|
||||
if page == self.pages[0] and 'cancelurl' in get_request().form:
|
||||
cancelurl = get_request().form['cancelurl']
|
||||
if not get_publisher().is_relatable_url(cancelurl):
|
||||
raise errors.RequestError('invalid cancel URL')
|
||||
form_data['__cancelurl'] = cancelurl
|
||||
session.add_magictoken(magictoken, form_data)
|
||||
|
||||
|
|
|
@ -386,6 +386,7 @@ class QommonPublisher(Publisher, object):
|
|||
defaults = {
|
||||
'options': {
|
||||
'unused-files-behaviour': 'remove',
|
||||
'relatable-hosts': '',
|
||||
},
|
||||
}
|
||||
if self.site_options is None:
|
||||
|
@ -956,6 +957,23 @@ class QommonPublisher(Publisher, object):
|
|||
d['manager_homepage_title'] = d.get('portal_agent_title')
|
||||
return d
|
||||
|
||||
def is_relatable_url(self, url):
|
||||
parsed_url = urllib.urlparse(url)
|
||||
if not parsed_url.netloc:
|
||||
return True
|
||||
if parsed_url.netloc == urllib.urlparse(self.get_frontoffice_url()).netloc:
|
||||
return True
|
||||
if parsed_url.netloc == urllib.urlparse(self.get_backoffice_url()).netloc:
|
||||
return True
|
||||
if parsed_url.netloc in [x.strip() for x in self.get_site_option('relatable-hosts').split(',')]:
|
||||
return True
|
||||
try:
|
||||
if parsed_url.netloc in self.site_options.options('api-secrets'):
|
||||
return True
|
||||
except ConfigParser.NoSectionError:
|
||||
pass
|
||||
return False
|
||||
|
||||
extra_sources = []
|
||||
@classmethod
|
||||
def register_extra_source(cls, source):
|
||||
|
|
Loading…
Reference in New Issue