This is an automated email from the ASF dual-hosted git repository. kaxilnaik pushed a commit to branch v1-10-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 9818932bee64bd5b0bb7433b8154b2b8d0b3feb4 Author: Kaxil Naik <[email protected]> AuthorDate: Wed Nov 18 21:46:36 2020 +0000 Webserver: Further Sanitize values passed to origin param (#12459) Follow-up of https://github.com/apache/airflow/pull/10334 --- airflow/www/views.py | 8 +++++++- airflow/www_rbac/views.py | 8 +++++++- tests/www/test_views.py | 6 +++++- tests/www_rbac/test_views.py | 5 ++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/airflow/www/views.py b/airflow/www/views.py index 0c412d9..d34df93 100644 --- a/airflow/www/views.py +++ b/airflow/www/views.py @@ -55,7 +55,7 @@ from past.builtins import basestring from pygments import highlight, lexers import six from pygments.formatters.html import HtmlFormatter -from six.moves.urllib.parse import quote, unquote, urlparse +from six.moves.urllib.parse import parse_qsl, quote, unquote, urlencode, urlparse from sqlalchemy import or_, desc, and_, union_all from wtforms import ( @@ -335,7 +335,13 @@ def get_safe_url(url): valid_schemes = ['http', 'https', ''] valid_netlocs = [request.host, ''] + if not url: + return "/admin/" + parsed = urlparse(url) + + query = parse_qsl(parsed.query, keep_blank_values=True) + url = parsed._replace(query=urlencode(query)).geturl() if parsed.scheme in valid_schemes and parsed.netloc in valid_netlocs: return url except Exception as e: # pylint: disable=broad-except diff --git a/airflow/www_rbac/views.py b/airflow/www_rbac/views.py index 8afcc27..793748a 100644 --- a/airflow/www_rbac/views.py +++ b/airflow/www_rbac/views.py @@ -31,7 +31,7 @@ from datetime import timedelta from urllib.parse import unquote import six -from six.moves.urllib.parse import quote, urlparse +from six.moves.urllib.parse import parse_qsl, quote, urlencode, urlparse import pendulum import sqlalchemy as sqla @@ -95,7 +95,13 @@ def get_safe_url(url): valid_schemes = ['http', 'https', ''] valid_netlocs = [request.host, ''] + if not url: + return url_for('Airflow.index') + parsed = urlparse(url) + + query = parse_qsl(parsed.query, keep_blank_values=True) + url = parsed._replace(query=urlencode(query)).geturl() if parsed.scheme in valid_schemes and parsed.netloc in valid_netlocs: return url except Exception as e: # pylint: disable=broad-except diff --git a/tests/www/test_views.py b/tests/www/test_views.py index 438830c..671c46f 100644 --- a/tests/www/test_views.py +++ b/tests/www/test_views.py @@ -1120,6 +1120,11 @@ class TestTriggerDag(unittest.TestCase): ("javascript:alert(1)", "/admin/"), ("http://google.com", "/admin/"), ( + "%2Fadmin%2Fairflow%2Ftree%3Fdag_id%3Dexample_bash_operator" + "&dag_id=example_bash_operator';alert(33)//", + "/admin/airflow/tree?dag_id=example_bash_operator" + ), + ( "%2Fadmin%2Fairflow%2Ftree%3Fdag_id%3Dexample_bash_operator&dag_id=example_bash_operator", "/admin/airflow/tree?dag_id=example_bash_operator" ), @@ -1127,7 +1132,6 @@ class TestTriggerDag(unittest.TestCase): "%2Fadmin%2Fairflow%2Fgraph%3Fdag_id%3Dexample_bash_operator&dag_id=example_bash_operator", "/admin/airflow/graph?dag_id=example_bash_operator" ), - ("", ""), ]) def test_trigger_dag_form_origin_url(self, test_origin, expected_origin): test_dag_id = "example_bash_operator" diff --git a/tests/www_rbac/test_views.py b/tests/www_rbac/test_views.py index 9b019bd..a17fab8 100644 --- a/tests/www_rbac/test_views.py +++ b/tests/www_rbac/test_views.py @@ -2247,9 +2247,12 @@ class TestTriggerDag(TestBase): @parameterized.expand([ ("javascript:alert(1)", "/home"), ("http://google.com", "/home"), + ( + "%2Ftree%3Fdag_id%3Dexample_bash_operator';alert(33)//", + "/tree?dag_id=example_bash_operator%27&alert%2833%29%2F%2F=", + ), ("%2Ftree%3Fdag_id%3Dexample_bash_operator", "/tree?dag_id=example_bash_operator"), ("%2Fgraph%3Fdag_id%3Dexample_bash_operator", "/graph?dag_id=example_bash_operator"), - ("", ""), ]) def test_trigger_dag_form_origin_url(self, test_origin, expected_origin): test_dag_id = "example_bash_operator"
