From fce150fcf723681683733e15b0822c5190114bf9 Mon Sep 17 00:00:00 2001 From: Andrew Klychkov Date: Tue, 12 May 2020 09:33:42 +0300 Subject: [PATCH] postgresql_copy: add trust_input parameter (#313) * postgresql_copy: add trust_input parameter * add changelog fragment --- ...esql_copy_add_trust_input_session_role.yml | 2 ++ .../database/postgresql/postgresql_copy.py | 28 +++++++++++++++++-- .../tasks/postgresql_copy_initial.yml | 23 +++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/313-postgresql_copy_add_trust_input_session_role.yml diff --git a/changelogs/fragments/313-postgresql_copy_add_trust_input_session_role.yml b/changelogs/fragments/313-postgresql_copy_add_trust_input_session_role.yml new file mode 100644 index 0000000000..5637944bae --- /dev/null +++ b/changelogs/fragments/313-postgresql_copy_add_trust_input_session_role.yml @@ -0,0 +1,2 @@ +minor_changes: +- postgresql_copy - add the ``trust_input`` parameter (https://github.com/ansible-collections/community.general/pull/313). diff --git a/plugins/modules/database/postgresql/postgresql_copy.py b/plugins/modules/database/postgresql/postgresql_copy.py index 071d339974..ad8db9b7cd 100644 --- a/plugins/modules/database/postgresql/postgresql_copy.py +++ b/plugins/modules/database/postgresql/postgresql_copy.py @@ -75,7 +75,12 @@ 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 parameters are potentially dangerous. + - It makes sense to use C(yes) only when SQL injections are possible. + type: bool + default: yes notes: - Supports PostgreSQL version 9.4+. - COPY command is only allowed to database superusers. @@ -182,7 +187,10 @@ except ImportError: pass from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.database import pg_quote_identifier +from ansible_collections.community.general.plugins.module_utils.database import ( + check_input, + pg_quote_identifier, +) from ansible_collections.community.general.plugins.module_utils.postgres import ( connect_to_db, exec_sql, @@ -340,6 +348,7 @@ def main(): program=dict(type='bool', default=False), db=dict(type='str', aliases=['login_db']), session_role=dict(type='str'), + trust_input=dict(type='bool', default=True), ) module = AnsibleModule( argument_spec=argument_spec, @@ -351,6 +360,21 @@ def main(): ] ) + if not module.params['trust_input']: + # Check input for potentially dangerous elements: + opt_list = None + if module.params['options']: + opt_list = ['%s %s' % (key, val) for (key, val) in iteritems(module.params['options'])] + + check_input(module, + module.params['copy_to'], + module.params['copy_from'], + module.params['src'], + module.params['dst'], + opt_list, + module.params['columns'], + module.params['session_role']) + # Note: we don't need to check mutually exclusive params here, because they are # checked automatically by AnsibleModule (mutually_exclusive=[] list above). if module.params.get('copy_from') and not module.params.get('dst'): diff --git a/tests/integration/targets/postgresql_copy/tasks/postgresql_copy_initial.yml b/tests/integration/targets/postgresql_copy/tasks/postgresql_copy_initial.yml index 62ab605143..cd9981e943 100644 --- a/tests/integration/targets/postgresql_copy/tasks/postgresql_copy_initial.yml +++ b/tests/integration/targets/postgresql_copy/tasks/postgresql_copy_initial.yml @@ -52,6 +52,7 @@ <<: *pg_parameters copy_to: '{{ data_file_txt }}' src: '{{ test_table }}' + trust_input: no - assert: that: @@ -76,6 +77,7 @@ <<: *pg_parameters copy_from: '{{ data_file_txt }}' dst: '{{ test_table }}' + trust_input: no - assert: that: @@ -101,18 +103,35 @@ <<: *pg_parameters copy_to: '{{ data_file_txt }}' src: non_existent_table + trust_input: no - assert: that: - result.failed == true - result.queries is not defined + - name: postgresql_copy - check trust_input + <<: *task_parameters + postgresql_copy: + <<: *pg_parameters + copy_to: '{{ data_file_txt }}' + src: '{{ test_table }}' + session_role: 'curious.anonymous"; SELECT * FROM information_schema.tables; --' + trust_input: no + ignore_errors: yes + + - assert: + that: + - result is failed + - result.msg is search('is potentially dangerous') + - name: postgresql_copy - copy test table data to data_file_txt <<: *task_parameters postgresql_copy: <<: *pg_parameters copy_to: '{{ data_file_txt }}' src: '{{ test_table }}' + trust_input: no - assert: that: @@ -142,6 +161,7 @@ - name options: format: csv + trust_input: no - assert: that: @@ -170,6 +190,7 @@ - name options: format: csv + trust_input: no - assert: that: @@ -198,6 +219,7 @@ columns: id, name options: delimiter: '|' + trust_input: no when: ansible_distribution != 'FreeBSD' - assert: @@ -218,6 +240,7 @@ columns: id, name options: delimiter: ',' + trust_input: no - assert: that: