summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Henkel <tobias.henkel@bmw.de>2019-02-17 17:10:55 +0100
committerTobias Henkel <tobias.henkel@bmw.de>2019-03-11 17:49:38 +0100
commit5ae25f004a32ea76558564612903cef917c3e5b9 (patch)
tree9a4ace98963a49c246c341844625bd13701d0cc1
parent3c73474c0775ad21712c86502096a5ce64e5ac35 (diff)
downloadzuul-5ae25f004a32ea76558564612903cef917c3e5b9.tar.gz
Prevent local code execution via the raw module3.6.1
The raw module had not been restricted to remote nodes so jobs could run arbitrary code on the executor. Change-Id: I1b37eac65ef59ca749f55117a678c38969e86ead
-rw-r--r--releasenotes/notes/localhost-raw-d841413f8743f8b8.yaml5
-rw-r--r--tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-delegate.yaml3
-rw-r--r--tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-localhost.yaml11
-rw-r--r--tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/main.yaml5
-rw-r--r--tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/script-delegate.yaml11
-rw-r--r--tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-localhost/tasks/main.yaml10
-rw-r--r--tests/remote/test_remote_action_modules.py6
-rw-r--r--zuul/ansible/action/raw.py32
-rw-r--r--zuul/ansible/action/raw.pyi0
9 files changed, 83 insertions, 0 deletions
diff --git a/releasenotes/notes/localhost-raw-d841413f8743f8b8.yaml b/releasenotes/notes/localhost-raw-d841413f8743f8b8.yaml
new file mode 100644
index 000000000..33854ca6f
--- /dev/null
+++ b/releasenotes/notes/localhost-raw-d841413f8743f8b8.yaml
@@ -0,0 +1,5 @@
+---
+security:
+ - |
+ The raw module had not been blocked for local tasks. This could be used
+ to bypass protection and execute commands on the executor.
diff --git a/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-delegate.yaml b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-delegate.yaml
new file mode 100644
index 000000000..0768287e9
--- /dev/null
+++ b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-delegate.yaml
@@ -0,0 +1,3 @@
+- hosts: all
+ roles:
+ - raw-test-delegate
diff --git a/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-localhost.yaml b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-localhost.yaml
new file mode 100644
index 000000000..8c2970229
--- /dev/null
+++ b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/raw-localhost.yaml
@@ -0,0 +1,11 @@
+- hosts: localhost
+ roles:
+ - raw-test-localhost
+
+- hosts: 127.0.0.1
+ roles:
+ - raw-test-localhost
+
+- hosts: "::1"
+ roles:
+ - raw-test-localhost
diff --git a/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/main.yaml b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/main.yaml
new file mode 100644
index 000000000..ccdf9a422
--- /dev/null
+++ b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/main.yaml
@@ -0,0 +1,5 @@
+- include: script-delegate.yaml
+ with_items:
+ - ::1
+ - 127.0.0.1
+ - localhost
diff --git a/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/script-delegate.yaml b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/script-delegate.yaml
new file mode 100644
index 000000000..339c1b724
--- /dev/null
+++ b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-delegate/tasks/script-delegate.yaml
@@ -0,0 +1,11 @@
+- name: Raw
+ raw: echo 123
+ delegate_to: "{{ item }}"
+ register: result
+ ignore_errors: true
+
+- assert:
+ that:
+ - "result.failed == true"
+ - "'Executing local code is prohibited' in result.msg"
+ msg: Raw must fail due to local code execution restriction
diff --git a/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-localhost/tasks/main.yaml b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-localhost/tasks/main.yaml
new file mode 100644
index 000000000..5b0f8c68d
--- /dev/null
+++ b/tests/fixtures/config/remote-action-modules/git/org_project/playbooks/roles/raw-test-localhost/tasks/main.yaml
@@ -0,0 +1,10 @@
+- name: Raw
+ raw: echo 123
+ register: result
+ ignore_errors: true
+
+- assert:
+ that:
+ - "result.failed == true"
+ - "'Executing local code is prohibited' in result.msg"
+ msg: Script must fail due to local code execution restriction
diff --git a/tests/remote/test_remote_action_modules.py b/tests/remote/test_remote_action_modules.py
index c8198cbc9..4e2881eaf 100644
--- a/tests/remote/test_remote_action_modules.py
+++ b/tests/remote/test_remote_action_modules.py
@@ -147,6 +147,12 @@ class TestActionModules(AnsibleZuulTestCase):
def test_raw_module(self):
self._run_job('raw-good', 'SUCCESS')
+ # raw-delegate does multiple tests with various delegates. It
+ # asserts by itself within ansible so we
+ # expect SUCCESS here.
+ self._run_job('raw-delegate', 'SUCCESS')
+ self._run_job('raw-localhost', 'SUCCESS')
+
def test_script_module(self):
self._run_job('script-good', 'SUCCESS')
diff --git a/zuul/ansible/action/raw.py b/zuul/ansible/action/raw.py
new file mode 100644
index 000000000..fb1e1a6e3
--- /dev/null
+++ b/zuul/ansible/action/raw.py
@@ -0,0 +1,32 @@
+# Copyright 2019 BMW Group
+#
+# This module is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this software. If not, see <http://www.gnu.org/licenses/>.
+
+
+from ansible.errors import AnsibleError
+from zuul.ansible import paths
+raw = paths._import_ansible_action_plugin("raw")
+
+
+class ActionModule(raw.ActionModule):
+
+ def run(self, tmp=None, task_vars=None):
+
+ if not paths._is_official_module(self):
+ return paths._fail_module_dict(self._task.action)
+
+ if paths._is_localhost_task(self):
+ raise AnsibleError("Executing local code is prohibited")
+
+ return super(ActionModule, self).run(tmp, task_vars)
diff --git a/zuul/ansible/action/raw.pyi b/zuul/ansible/action/raw.pyi
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/zuul/ansible/action/raw.pyi