From 27a4a888e946728d9bb33b78ec604e08d4a93f89 Mon Sep 17 00:00:00 2001 From: Ash Berlin-Taylor Date: Wed, 9 Jan 2019 23:06:42 +0000 Subject: [PATCH] [AIRFLOW-3655] Escape links generated in model views (#4463) --- airflow/www/views.py | 9 ++++++--- airflow/www_rbac/views.py | 3 ++- tests/www_rbac/test_views.py | 7 +++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/airflow/www/views.py b/airflow/www/views.py index d097e54b85c05..9f34b9c440085 100644 --- a/airflow/www/views.py +++ b/airflow/www/views.py @@ -131,7 +131,8 @@ def dag_run_link(v, c, m, p): dag_id=m.dag_id, run_id=m.run_id, execution_date=m.execution_date) - return Markup('{m.run_id}'.format(**locals())) + title = escape(m.run_id) + return Markup('{title}'.format(**locals())) def task_instance_link(v, c, m, p): @@ -202,12 +203,14 @@ def label_link(v, c, m, p): url = url_for( 'airflow.chart', chart_id=m.id, iteration_no=m.iteration_no, **default_params) - return Markup("{m.label}".format(**locals())) + title = escape(m.label) + return Markup("{title}".format(**locals())) def pool_link(v, c, m, p): + title = escape(m.pool) url = '/admin/taskinstance/?flt1_pool_equals=' + m.pool - return Markup("{m.pool}".format(**locals())) + return Markup("{title}".format(**locals())) def pygment_html_render(s, lexer=lexers.TextLexer): diff --git a/airflow/www_rbac/views.py b/airflow/www_rbac/views.py index c916941112df2..767ef4aef037c 100644 --- a/airflow/www_rbac/views.py +++ b/airflow/www_rbac/views.py @@ -36,7 +36,7 @@ import sqlalchemy as sqla from flask import ( redirect, request, Markup, Response, render_template, - make_response, flash, jsonify) + make_response, flash, jsonify, escape) from flask._compat import PY2 from flask_appbuilder import BaseView, ModelView, expose, has_access from flask_appbuilder.actions import action @@ -1974,6 +1974,7 @@ def pool_link(attr): pool_id = attr.get('pool') if pool_id is not None: url = '/taskinstance/list/?_flt_3_pool=' + str(pool_id) + pool_id = escape(pool_id) return Markup("{pool_id}".format(**locals())) else: return Markup('Invalid') diff --git a/tests/www_rbac/test_views.py b/tests/www_rbac/test_views.py index 93f6bfd8f7142..3e583507b9ba5 100644 --- a/tests/www_rbac/test_views.py +++ b/tests/www_rbac/test_views.py @@ -244,6 +244,13 @@ def test_create_pool_with_empty_name(self): follow_redirects=True) self.check_content_in_response('This field is required.', resp) + def test_odd_name(self): + self.pool['pool'] = 'test-pool' + self.session.add(models.Pool(**self.pool)) + self.session.commit() + resp = self.client.get('/pool/list/') + self.check_content_in_response('test-pool<script>', resp) + class TestMountPoint(unittest.TestCase): def setUp(self):