summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Unterwaditzer <markus@unterwaditzer.net>2017-05-16 08:35:50 +0200
committerMarkus Unterwaditzer <markus@unterwaditzer.net>2017-05-16 08:35:50 +0200
commit2497866d7eafa64ca5eb4fb3d1747c05036bf318 (patch)
treeb5736fd66aa3bce493eaee6eaf7d8b8ad6b02126
parent940baabf298f8b57340651c985bb30c64c2e4ca3 (diff)
downloadwerkzeug-2497866d7eafa64ca5eb4fb3d1747c05036bf318.tar.gz
Port of pallets/flask#2284 (safe_join bug)
-rw-r--r--CHANGES1
-rw-r--r--werkzeug/security.py24
2 files changed, 16 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES
index 267196f7..bd99b89e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,7 @@ yet to be released
- Fix regression: Pull request ``#892`` prevented Werkzeug from correctly
logging the IP of a remote client behind a reverse proxy, even when using
`ProxyFix`.
+- Fix a bug in `safe_join` on Windows.
Version 0.12.1
--------------
diff --git a/werkzeug/security.py b/werkzeug/security.py
index f5238771..902226e6 100644
--- a/werkzeug/security.py
+++ b/werkzeug/security.py
@@ -248,17 +248,23 @@ def check_password_hash(pwhash, password):
return safe_str_cmp(_hash_internal(method, salt, password)[0], hashval)
-def safe_join(directory, filename):
- """Safely join `directory` and `filename`. If this cannot be done,
- this function returns ``None``.
+def safe_join(directory, *pathnames):
+ """Safely join `directory` and one or more untrusted `pathnames`. If this
+ cannot be done, this function returns ``None``.
:param directory: the base directory.
:param filename: the untrusted filename relative to that directory.
"""
- filename = posixpath.normpath(filename)
- for sep in _os_alt_seps:
- if sep in filename:
+ parts = [directory]
+ for filename in pathnames:
+ if filename != '':
+ filename = posixpath.normpath(filename)
+ for sep in _os_alt_seps:
+ if sep in filename:
+ return None
+ if os.path.isabs(filename) or \
+ filename == '..' or \
+ filename.startswith('../'):
return None
- if os.path.isabs(filename) or filename.startswith('../'):
- return None
- return os.path.join(directory, filename)
+ parts.append(filename)
+ return posixpath.join(*parts)