You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ka...@apache.org on 2020/11/18 19:54:09 UTC
[airflow] branch origin-fix created (now d6a1ae1)
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a change to branch origin-fix
in repository https://gitbox.apache.org/repos/asf/airflow.git.
at d6a1ae1 Webserver: Further Sanitize values passed to origin param
This branch includes the following new commits:
new d6a1ae1 Webserver: Further Sanitize values passed to origin param
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[airflow] 01/01: Webserver: Further Sanitize values passed to
origin param
Posted by ka...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch origin-fix
in repository https://gitbox.apache.org/repos/asf/airflow.git
commit d6a1ae1a7ddb1bb67f1d35dc8a72d387575176a1
Author: Kaxil Naik <ka...@gmail.com>
AuthorDate: Wed Nov 18 19:52:14 2020 +0000
Webserver: Further Sanitize values passed to origin param
Follow-up of https://github.com/apache/airflow/pull/10334
---
airflow/www/views.py | 7 ++++++-
tests/www/test_views.py | 26 +++++++++++++++++++++++++-
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/airflow/www/views.py b/airflow/www/views.py
index fc2d2d0..bc4ac40 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -28,7 +28,7 @@ from collections import defaultdict
from datetime import datetime, timedelta
from json import JSONDecodeError
from typing import Dict, List, Optional, Tuple
-from urllib.parse import unquote, urlparse
+from urllib.parse import parse_qsl, unquote, urlencode, urlparse
import lazy_object_proxy
import nvd3
@@ -108,8 +108,13 @@ def get_safe_url(url):
valid_schemes = ['http', 'https', '']
valid_netlocs = [request.host, '']
+ # Remove single quotes
+ url = url.replace("'", "")
parsed = urlparse(url)
+ query = parse_qsl(parsed.query)
+ url = parsed._replace(query=urlencode(query)).geturl()
+
if parsed.scheme in valid_schemes and parsed.netloc in valid_netlocs:
return url
diff --git a/tests/www/test_views.py b/tests/www/test_views.py
index c3e9963..39fe6d8 100644
--- a/tests/www/test_views.py
+++ b/tests/www/test_views.py
@@ -62,7 +62,7 @@ from airflow.utils.state import State
from airflow.utils.timezone import datetime
from airflow.utils.types import DagRunType
from airflow.www import app as application
-from airflow.www.views import ConnectionModelView
+from airflow.www.views import ConnectionModelView, get_safe_url
from tests.test_utils import fab_utils
from tests.test_utils.asserts import assert_queries_count
from tests.test_utils.config import conf_vars
@@ -2772,6 +2772,7 @@ class TestTriggerDag(TestBase):
[
("javascript:alert(1)", "/home"),
("http://google.com", "/home"),
+ ("%2Ftree%3Fdag_id%3Dexample_bash_operator%27;alert(33)//", "/tree?dag_id=example_bash_operator"),
("%2Ftree%3Fdag_id%3Dexample_bash_operator", "/tree?dag_id=example_bash_operator"),
("%2Fgraph%3Fdag_id%3Dexample_bash_operator", "/graph?dag_id=example_bash_operator"),
]
@@ -3293,3 +3294,26 @@ class TestDecorators(TestBase):
self.check_last_log(
"example_bash_operator", event="clear", execution_date=self.EXAMPLE_DAG_DEFAULT_DATE
)
+
+
+class TestHelperFunctions(unittest.TestCase):
+ @parameterized.expand(
+ [
+ # ("javascript:alert(1)", "/home"),
+ ("http://google.com", "/home"),
+ (
+ "http://localhost:8080/trigger?dag_id=test_dag&origin=%2Ftree%3Fdag_id%test_dag';alert(33)//",
+ "http://localhost:8080/trigger?dag_id=test_dag&origin=%2Ftree%3Fdag_id%25test_dag",
+ ),
+ (
+ "http://localhost:8080/trigger?dag_id=test_dag&origin=%2Ftree%3Fdag_id%test_dag",
+ "http://localhost:8080/trigger?dag_id=test_dag&origin=%2Ftree%3Fdag_id%25test_dag",
+ ),
+ ]
+ )
+ @mock.patch("airflow.www.views.url_for")
+ @mock.patch("airflow.www.views.request")
+ def test_get_safe_url(self, test_url, expected_url, mock_req, mock_url_for):
+ mock_req.host = 'localhost:8080'
+ mock_url_for.return_value = "/home"
+ self.assertEqual(get_safe_url(test_url), expected_url)