diff options
author | Brian Coca <bcoca@users.noreply.github.com> | 2019-08-12 21:06:35 -0400 |
---|---|---|
committer | Toshio Kuratomi <a.badger@gmail.com> | 2019-08-12 18:06:35 -0700 |
commit | d728127310b4f3a40ce8b9df3affb88ffaeea073 (patch) | |
tree | d02a6a79383c4aa22b8eaf1691198657a58c0db8 | |
parent | 6444278f44e02405752cc143ec4955839086a569 (diff) | |
download | ansible-d728127310b4f3a40ce8b9df3affb88ffaeea073.tar.gz |
prevent templating of passwords from prompt (#59246) (#59553)
* 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.yml | 2 | ||||
-rw-r--r-- | lib/ansible/cli/__init__.py | 8 | ||||
-rw-r--r-- | lib/ansible/utils/unsafe_proxy.py | 15 |
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 86d248098b..e941743ac7 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 @@ -336,6 +337,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 9f7de697e4..7b8edab24b 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 |