diff --git a/awx/main/models/mixins.py b/awx/main/models/mixins.py index 1186797b09..82cbeca5de 100644 --- a/awx/main/models/mixins.py +++ b/awx/main/models/mixins.py @@ -163,6 +163,19 @@ class SurveyJobTemplateMixin(models.Model): def _survey_element_validation(self, survey_element, data): errors = [] + # make a copy of the data to break references (so that we don't + # inadvertently expose unencrypted default passwords as we validate) + data = data.copy() + if all([ + survey_element['type'] == "password", + data.get(survey_element['variable']) == '$encrypted$' + ]): + # replace encrypted password defaults so we don't validate on + # $encrypted$ + data[survey_element['variable']] = decrypt_value( + get_encryption_key('value', pk=None), + survey_element['default'] + ) if survey_element['variable'] not in data and survey_element['required']: errors.append("'%s' value missing" % survey_element['variable']) elif survey_element['type'] in ["textarea", "text", "password"]: diff --git a/awx/main/tests/unit/models/test_survey_models.py b/awx/main/tests/unit/models/test_survey_models.py index d283c57081..6362a25e61 100644 --- a/awx/main/tests/unit/models/test_survey_models.py +++ b/awx/main/tests/unit/models/test_survey_models.py @@ -8,6 +8,7 @@ from awx.main.models import ( JobTemplate, WorkflowJobTemplate ) +from awx.main.utils.encryption import encrypt_value @pytest.fixture @@ -143,6 +144,21 @@ def test_optional_survey_question_defaults( assert 'c' not in defaulted_extra_vars['extra_vars'] +@pytest.mark.survey +def test_encrypted_default_validation(survey_spec_factory): + element = { + "required": True, + "default": encrypt_value("test1234", pk=None), + "variable": "x", + "min": 0, + "max": 8, + "type": "password", + } + spec = survey_spec_factory([element]) + jt = JobTemplate(name="test-jt", survey_spec=spec, survey_enabled=True) + assert not len(jt.survey_variable_validation({'x': '$encrypted$'})) + + @pytest.mark.survey class TestWorkflowSurveys: def test_update_kwargs_survey_defaults(self, survey_spec_factory):