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 e9a37f8e31)

* 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 490f17c7f9)
This commit is contained in:
Brian Coca 2019-08-12 21:06:01 -04:00 committed by Toshio Kuratomi
parent fcf8dc8d0c
commit 4b5aed4e5a
3 changed files with 22 additions and 3 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- resolves CVE-2019-10206, by avoiding templating passwords from prompt as it is probable they have special characters.

View file

@ -42,6 +42,7 @@ from ansible.parsing.dataloader import DataLoader
from ansible.release import __version__ from ansible.release import __version__
from ansible.utils.path import unfrackpath from ansible.utils.path import unfrackpath
from ansible.utils.vars import load_extra_vars, load_options_vars 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.vars.manager import VariableManager
from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret
@ -342,6 +343,13 @@ class CLI(with_metaclass(ABCMeta, object)):
except EOFError: except EOFError:
pass 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) return (sshpass, becomepass)
def normalize_become_options(self): def normalize_become_options(self):

View file

@ -55,7 +55,7 @@ __metaclass__ = type
from collections import Mapping, MutableSequence, Set 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 from ansible.module_utils._text import to_text
@ -70,15 +70,24 @@ class AnsibleUnsafeText(text_type, AnsibleUnsafe):
pass pass
class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
pass
class UnsafeProxy(object): class UnsafeProxy(object):
def __new__(cls, obj, *args, **kwargs): def __new__(cls, obj, *args, **kwargs):
if isinstance(obj, AnsibleUnsafe):
# Already marked unsafe
return obj
# In our usage we should only receive unicode strings. # In our usage we should only receive unicode strings.
# This conditional and conversion exists to sanity check the values # 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 # we're given but we may want to take it out for testing and sanitize
# our input instead. # 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): if isinstance(obj, string_types):
obj = to_text(obj, errors='surrogate_or_strict') obj = AnsibleUnsafeText(to_text(obj, errors='surrogate_or_strict'))
return AnsibleUnsafeText(obj)
return obj return obj