summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Coca <bcoca@users.noreply.github.com>2019-08-12 21:06:01 -0400
committerToshio Kuratomi <a.badger@gmail.com>2019-08-12 18:06:01 -0700
commit4b5aed4e5af4c7aab621662f50a289e99b8ac393 (patch)
treefbad9e704aa88e3c94c9b01d4beeca377fed44ba
parentfcf8dc8d0cb5cb835030eeca65640ff05923c376 (diff)
downloadansible-4b5aed4e5af4c7aab621662f50a289e99b8ac393.tar.gz
prevent templating of passwords from prompt (#59246) (#59554)
* prevent templating of passwords from prompt (#59246) * prevent templating of passwords from prompt fixes CVE-2019-10206 (cherry picked from commit e9a37f8e3171105941892a86a1587de18126ec5b) * Improve performane of UnsafeProxy __new__ This adds an early return to the __new__ method of the UnsafeProxy object which avoids creating the unsafe object if the incoming object is already unsafe. (cherry picked from commit c1e23c22a9fedafaaa88c2119b26dc123ff1392e) (cherry picked from commit 490f17c7f959ce153765c1f033fdc30becf0faf7)
-rw-r--r--changelogs/fragments/dont_template_passwords_from_prompt.yml2
-rw-r--r--lib/ansible/cli/__init__.py8
-rw-r--r--lib/ansible/utils/unsafe_proxy.py15
3 files changed, 22 insertions, 3 deletions
diff --git a/changelogs/fragments/dont_template_passwords_from_prompt.yml b/changelogs/fragments/dont_template_passwords_from_prompt.yml
new file mode 100644
index 0000000000..86a0e6122f
--- /dev/null
+++ b/changelogs/fragments/dont_template_passwords_from_prompt.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - resolves CVE-2019-10206, by avoiding templating passwords from prompt as it is probable they have special characters.
diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py
index 380ddc4e2a..76d652f7c8 100644
--- a/lib/ansible/cli/__init__.py
+++ b/lib/ansible/cli/__init__.py
@@ -42,6 +42,7 @@ from ansible.parsing.dataloader import DataLoader
from ansible.release import __version__
from ansible.utils.path import unfrackpath
from ansible.utils.vars import load_extra_vars, load_options_vars
+from ansible.utils.unsafe_proxy import AnsibleUnsafeBytes
from ansible.vars.manager import VariableManager
from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret
@@ -342,6 +343,13 @@ class CLI(with_metaclass(ABCMeta, object)):
except EOFError:
pass
+ # we 'wrap' the passwords to prevent templating as
+ # they can contain special chars and trigger it incorrectly
+ if sshpass:
+ sshpass = AnsibleUnsafeBytes(sshpass)
+ if becomepass:
+ becomepass = AnsibleUnsafeBytes(becomepass)
+
return (sshpass, becomepass)
def normalize_become_options(self):
diff --git a/lib/ansible/utils/unsafe_proxy.py b/lib/ansible/utils/unsafe_proxy.py
index 963798a087..6221e73393 100644
--- a/lib/ansible/utils/unsafe_proxy.py
+++ b/lib/ansible/utils/unsafe_proxy.py
@@ -55,7 +55,7 @@ __metaclass__ = type
from collections import Mapping, MutableSequence, Set
-from ansible.module_utils.six import string_types, text_type
+from ansible.module_utils.six import string_types, text_type, binary_type
from ansible.module_utils._text import to_text
@@ -70,15 +70,24 @@ class AnsibleUnsafeText(text_type, AnsibleUnsafe):
pass
+class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
+ pass
+
+
class UnsafeProxy(object):
def __new__(cls, obj, *args, **kwargs):
+ if isinstance(obj, AnsibleUnsafe):
+ # Already marked unsafe
+ return obj
+
# In our usage we should only receive unicode strings.
# This conditional and conversion exists to sanity check the values
# we're given but we may want to take it out for testing and sanitize
# our input instead.
+ # Note that this does the wrong thing if we're *intentionall* passing a byte string to this
+ # function.
if isinstance(obj, string_types):
- obj = to_text(obj, errors='surrogate_or_strict')
- return AnsibleUnsafeText(obj)
+ obj = AnsibleUnsafeText(to_text(obj, errors='surrogate_or_strict'))
return obj