aboutsummaryrefslogtreecommitdiff
path: root/kolla
diff options
context:
space:
mode:
Diffstat (limited to 'kolla')
-rw-r--r--kolla/image/kolla_worker.py5
-rw-r--r--kolla/tests/test_build.py67
-rw-r--r--kolla/tests/test_validate_all_file.py43
3 files changed, 113 insertions, 2 deletions
diff --git a/kolla/image/kolla_worker.py b/kolla/image/kolla_worker.py
index 680595f86..b60f0558f 100644
--- a/kolla/image/kolla_worker.py
+++ b/kolla/image/kolla_worker.py
@@ -23,6 +23,7 @@ import tempfile
import time
import jinja2
+import jinja2.sandbox
from kolla.common import config as common_config
from kolla.common import utils
from kolla.engine_adapter import engine
@@ -392,7 +393,7 @@ class KollaWorker(object):
'build_date': build_date,
'clean_package_cache': self.clean_package_cache,
'patches_path': self.patches_path}
- env = jinja2.Environment( # nosec: not used to render HTML
+ env = jinja2.sandbox.SandboxedEnvironment(
loader=jinja2.FileSystemLoader(self.working_dir))
env.filters.update(self._get_filters())
env.globals.update(self._get_methods())
@@ -405,7 +406,7 @@ class KollaWorker(object):
tpl_dict = self._merge_overrides(self.conf.template_override)
template_name = os.path.basename(list(tpl_dict.keys())[0])
values['parent_template'] = template
- env = jinja2.Environment( # nosec: not used to render HTML
+ env = jinja2.sandbox.SandboxedEnvironment(
loader=jinja2.DictLoader(tpl_dict))
env.filters.update(self._get_filters())
env.globals.update(self._get_methods())
diff --git a/kolla/tests/test_build.py b/kolla/tests/test_build.py
index deb2dfa10..82bcb7d6d 100644
--- a/kolla/tests/test_build.py
+++ b/kolla/tests/test_build.py
@@ -11,6 +11,7 @@
# limitations under the License.
import fixtures
+import jinja2
import os
import requests
import sys
@@ -579,6 +580,72 @@ class KollaWorkerTest(base.TestCase):
kolla.setup_working_dir()
kolla.set_time()
+ @mock.patch.dict(os.environ, {'http_proxy': 'http://test-proxy:8080'},
+ clear=False)
+ @mock.patch(engine_client)
+ def test_create_dockerfiles_env_http_proxy(self, mock_client):
+ tmpdir = self.useFixture(fixtures.TempDir()).path
+ base_dir = os.path.join(tmpdir, 'base')
+ os.makedirs(base_dir)
+ with open(os.path.join(base_dir, 'Dockerfile.j2'), 'w') as f:
+ f.write(
+ '{% if env.http_proxy %}'
+ 'ARG http_proxy={{ env.http_proxy }}'
+ '{% endif %}\n'
+ )
+ with mock.patch.object(build.KollaWorker, '_get_images_dir',
+ return_value=tmpdir):
+ kolla = build.KollaWorker(self.conf)
+ kolla.setup_working_dir()
+ kolla.find_dockerfiles()
+ kolla.create_dockerfiles()
+ dockerfile = os.path.join(kolla.working_dir, 'base', 'Dockerfile')
+ with open(dockerfile) as f:
+ content = f.read()
+ self.assertIn('http://test-proxy:8080', content)
+
+ @mock.patch(engine_client)
+ def test_create_dockerfiles_ssti_blocked(self, mock_client):
+ tmpdir = self.useFixture(fixtures.TempDir()).path
+ base_dir = os.path.join(tmpdir, 'base')
+ os.makedirs(base_dir)
+ with open(os.path.join(base_dir, 'Dockerfile.j2'), 'w') as f:
+ f.write(
+ "{{ self.__init__.__globals__['__builtins__']"
+ "['__import__']('os').popen('id').read() }}\n"
+ )
+ with mock.patch.object(build.KollaWorker, '_get_images_dir',
+ return_value=tmpdir):
+ kolla = build.KollaWorker(self.conf)
+ kolla.setup_working_dir()
+ kolla.find_dockerfiles()
+ self.assertRaises(jinja2.exceptions.SecurityError,
+ kolla.create_dockerfiles)
+
+ @mock.patch(engine_client)
+ def test_create_dockerfiles_template_override_ssti_blocked(
+ self, mock_client):
+ tmpdir = self.useFixture(fixtures.TempDir()).path
+ base_dir = os.path.join(tmpdir, 'base')
+ os.makedirs(base_dir)
+ with open(os.path.join(base_dir, 'Dockerfile.j2'), 'w') as f:
+ f.write('FROM {{ base_distro }}:{{ base_distro_tag }}\n')
+ override_file = os.path.join(
+ self.useFixture(fixtures.TempDir()).path, 'template_override.j2')
+ with open(override_file, 'w') as f:
+ f.write(
+ "{{ self.__init__.__globals__['__builtins__']"
+ "['__import__']('os').popen('id').read() }}\n"
+ )
+ self.conf.set_override('template_override', [override_file])
+ with mock.patch.object(build.KollaWorker, '_get_images_dir',
+ return_value=tmpdir):
+ kolla = build.KollaWorker(self.conf)
+ kolla.setup_working_dir()
+ kolla.find_dockerfiles()
+ self.assertRaises(jinja2.exceptions.SecurityError,
+ kolla.create_dockerfiles)
+
def _get_matched_images(self, images):
return [image for image in images
if image.status == utils.Status.MATCHED]
diff --git a/kolla/tests/test_validate_all_file.py b/kolla/tests/test_validate_all_file.py
new file mode 100644
index 000000000..04dab530e
--- /dev/null
+++ b/kolla/tests/test_validate_all_file.py
@@ -0,0 +1,43 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import importlib.util
+import os
+import tempfile
+from unittest import mock
+
+from kolla.tests import base
+
+_VALIDATE_SCRIPT = os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..', '..', 'tools',
+ 'validate-all-file.py'))
+_spec = importlib.util.spec_from_file_location('validate_all_file',
+ _VALIDATE_SCRIPT)
+validate_all_file = importlib.util.module_from_spec(_spec)
+_spec.loader.exec_module(validate_all_file)
+
+_SSTI_PAYLOAD = (
+ "{{ self.__init__.__globals__['__builtins__']"
+ "['__import__']('os').popen('id').read() }}"
+)
+
+
+class ValidateAllFileTest(base.TestCase):
+
+ def test_check_json_j2_ssti_blocked(self):
+ with tempfile.TemporaryDirectory() as tmpdir:
+ malicious = os.path.join(tmpdir, 'test.json.j2')
+ with open(malicious, 'w') as f:
+ f.write(_SSTI_PAYLOAD + '\n')
+ with mock.patch.object(validate_all_file, 'PROJECT_ROOT', tmpdir):
+ result = validate_all_file.check_json_j2()
+ self.assertEqual(1, result)