diff --git a/changelogs/fragments/158-postgresql_membership_add_trust_input_parameter.yml b/changelogs/fragments/158-postgresql_membership_add_trust_input_parameter.yml new file mode 100644 index 0000000000..8104d2ce6f --- /dev/null +++ b/changelogs/fragments/158-postgresql_membership_add_trust_input_parameter.yml @@ -0,0 +1,2 @@ +minor_changes: +- postgresql_membership - add the ``trust_input`` parameter (https://github.com/ansible-collections/community.general/pull/158). diff --git a/plugins/modules/database/postgresql/postgresql_membership.py b/plugins/modules/database/postgresql/postgresql_membership.py index 42c4eea4ef..04d8e58e4c 100644 --- a/plugins/modules/database/postgresql/postgresql_membership.py +++ b/plugins/modules/database/postgresql/postgresql_membership.py @@ -72,6 +72,11 @@ options: - Permissions checking for SQL commands is carried out as though the session_role were the one that had logged in originally. type: str + trust_input: + description: + - If C(no), check whether values of some parameters are potentially dangerous. + type: bool + default: yes seealso: - module: postgresql_user - module: postgresql_privs @@ -141,6 +146,7 @@ except ImportError: pass from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.database import check_input from ansible_collections.community.general.plugins.module_utils.postgres import ( connect_to_db, get_conn_params, @@ -162,6 +168,7 @@ def main(): state=dict(type='str', default='present', choices=['absent', 'present']), db=dict(type='str', aliases=['login_db']), session_role=dict(type='str'), + trust_input=dict(type='bool', default=True), ) module = AnsibleModule( @@ -173,6 +180,11 @@ def main(): target_roles = module.params['target_roles'] fail_on_role = module.params['fail_on_role'] state = module.params['state'] + session_role = module.params['session_role'] + trust_input = module.params['trust_input'] + if not trust_input: + # Check input for potentially dangerous elements: + check_input(module, groups, target_roles, session_role) conn_params = get_conn_params(module, module.params, warn_db_default=False) db_connection = connect_to_db(module, conn_params, autocommit=False) diff --git a/tests/integration/targets/postgresql_membership/defaults/main.yml b/tests/integration/targets/postgresql_membership/defaults/main.yml index 0e3d2f1ba9..7b1d49e44c 100644 --- a/tests/integration/targets/postgresql_membership/defaults/main.yml +++ b/tests/integration/targets/postgresql_membership/defaults/main.yml @@ -3,3 +3,4 @@ test_group2: group2 test_group3: group.with.dots test_user1: user1 test_user2: user.with.dots +dangerous_name: 'curious.anonymous"; SELECT * FROM information_schema.tables; --' diff --git a/tests/integration/targets/postgresql_membership/tasks/postgresql_membership_initial.yml b/tests/integration/targets/postgresql_membership/tasks/postgresql_membership_initial.yml index 5b7cc0439a..d8d7bb6b8a 100644 --- a/tests/integration/targets/postgresql_membership/tasks/postgresql_membership_initial.yml +++ b/tests/integration/targets/postgresql_membership/tasks/postgresql_membership_initial.yml @@ -345,3 +345,46 @@ that: - result is changed - result.queries == ["GRANT \"{{ test_group3 }}\" TO \"{{ test_user1 }}\""] + +############################# +# Check trust_input parameter + +- name: postgresql_membership - try to use dangerous input, don't trust + become_user: "{{ pg_user }}" + become: yes + postgresql_membership: + login_user: "{{ pg_user }}" + db: postgres + group: + - "{{ test_group3}}" + - "{{ dangerous_name }}" + user: "{{ test_user1 }}" + state: present + trust_input: no + register: result + ignore_errors: yes + +- assert: + that: + - result is failed + - result.msg == 'Passed input \'{{ dangerous_name }}\' is potentially dangerous' + +- name: postgresql_membership - try to use dangerous input, trust explicitly + become_user: "{{ pg_user }}" + become: yes + postgresql_membership: + login_user: "{{ pg_user }}" + db: postgres + group: + - "{{ test_group3}}" + - "{{ dangerous_name }}" + user: "{{ test_user1 }}" + state: present + trust_input: yes + register: result + ignore_errors: yes + +- assert: + that: + - result is failed + - result.msg == 'Role {{ dangerous_name }} does not exist'