Skip to content

Commit

Permalink
prevent templating of passwords from prompt (#59246) (#59553)
Browse files Browse the repository at this point in the history
* prevent templating of passwords from prompt (#59246)

* prevent templating of passwords from prompt

  fixes CVE-2019-10206

(cherry picked from commit e9a37f8)

* 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 c1e23c2)
(cherry picked from commit 490f17c)
  • Loading branch information
bcoca authored and abadger committed Aug 13, 2019
1 parent 6444278 commit d728127
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
2 changes: 2 additions & 0 deletions 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.
8 changes: 8 additions & 0 deletions lib/ansible/cli/__init__.py
Expand Up @@ -42,6 +42,7 @@
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

Expand Down Expand Up @@ -336,6 +337,13 @@ def ask_passwords(self):
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):
Expand Down
15 changes: 12 additions & 3 deletions lib/ansible/utils/unsafe_proxy.py
Expand Up @@ -55,7 +55,7 @@

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


Expand All @@ -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


Expand Down

0 comments on commit d728127

Please sign in to comment.