This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 87c5c9fa62 Fix failing get_safe_url tests for latest Python 3.8 and
3.9 (#31766)
87c5c9fa62 is described below
commit 87c5c9fa629317090ce65ec4c686596a2c4cd148
Author: Jarek Potiuk <[email protected]>
AuthorDate: Wed Jun 7 16:55:33 2023 +0200
Fix failing get_safe_url tests for latest Python 3.8 and 3.9 (#31766)
The latest release of Python 3.8 and 3.9 have been just released
that contain the fix to a security vulnerability backported to
those versions:
https://github.com/python/cpython/issues/102153
Release notes:
* https://www.python.org/downloads/release/python-3817/
* https://www.python.org/downloads/release/python-3917/
The fix improved sanitizing of the URLs and until Python 3.10 and
3.11 get released, we need to add the sanitization ourselves to
pass tests on all versions.
In order to improve security of airflow users and make the tests
work regardless whether the users have latest Python versions
released, we add extra sanitisation step to the URL to apply
the standard WHATWG specification.
---
airflow/www/views.py | 23 +++++++++++++++++++++++
tests/www/views/test_views.py | 2 +-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/airflow/www/views.py b/airflow/www/views.py
index 04671e6f53..cc08609096 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -153,6 +153,27 @@ def sanitize_args(args: dict[str, str]) -> dict[str, str]:
return {key: value for key, value in args.items() if not
key.startswith("_")}
+# Following the release of https://github.com/python/cpython/issues/102153 in
Python 3.8.17 and 3.9.17 on
+# June 6, 2023, we are adding extra sanitization of the urls passed to
get_safe_url method to make it works
+# the same way regardless if the user uses latest Python patchlevel versions
or not. This also follows
+# a recommended solution by the Python core team.
+#
+# From:
https://github.com/python/cpython/commit/d28bafa2d3e424b6fdcfd7ae7cde8e71d7177369
+#
+# We recommend that users of these APIs where the values may be used anywhere
+# with security implications code defensively. Do some verification within
your
+# code before trusting a returned component part. Does that ``scheme`` make
+# sense? Is that a sensible ``path``? Is there anything strange about that
+# ``hostname``? etc.
+#
+# C0 control and space to be stripped per WHATWG spec.
+# == "".join([chr(i) for i in range(0, 0x20 + 1)])
+_WHATWG_C0_CONTROL_OR_SPACE = (
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c"
+
"\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f "
+)
+
+
def get_safe_url(url):
"""Given a user-supplied URL, ensure it points to our web server."""
if not url:
@@ -163,6 +184,8 @@ def get_safe_url(url):
if ";" in unquote(url):
return url_for("Airflow.index")
+ url = url.lstrip(_WHATWG_C0_CONTROL_OR_SPACE)
+
host_url = urlsplit(request.host_url)
redirect_url = urlsplit(urljoin(request.host_url, url))
if not (redirect_url.scheme in ("http", "https") and host_url.netloc ==
redirect_url.netloc):
diff --git a/tests/www/views/test_views.py b/tests/www/views/test_views.py
index 0636ba16c7..e266b9b8c1 100644
--- a/tests/www/views/test_views.py
+++ b/tests/www/views/test_views.py
@@ -193,7 +193,7 @@ def test_task_dag_id_equals_filter(admin_client, url,
content):
[
("", "/home"),
("javascript:alert(1)", "/home"),
- (" javascript:alert(1)", "http://localhost:8080/ javascript:alert(1)"),
+ (" javascript:alert(1)", "/home"),
("http://google.com", "/home"),
("google.com", "http://localhost:8080/google.com"),
("\\/google.com", "http://localhost:8080/\\/google.com"),