Use secure path join
Change-Id: If0eeef8b025b1f3be863728a8def81d944873ac5 Closes-bug: #1729214
This commit is contained in:
parent
f73c89d25e
commit
6674e065da
|
@ -10,10 +10,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
import yaml
|
||||
|
||||
from murano.common.helpers import path
|
||||
from murano.packages import exceptions
|
||||
from murano.packages import package_base
|
||||
|
||||
|
@ -136,9 +135,9 @@ class CloudifyToscaPackage(package_base.PackageBase):
|
|||
}
|
||||
|
||||
def _get_inputs_outputs(self):
|
||||
path = os.path.join(
|
||||
entry_point_path = path.secure_join(
|
||||
self.source_directory, RESOURCES_DIR_NAME, self._entry_point)
|
||||
with open(path) as blueprint:
|
||||
with open(entry_point_path) as blueprint:
|
||||
data = yaml.safe_load(blueprint)
|
||||
return data.get('inputs') or {}, data.get('outputs') or {}
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright (c) 2017 Mirantis Inc.
|
||||
#
|
||||
# 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 os.path
|
||||
|
||||
|
||||
def secure_join(*parts):
|
||||
"""Secure version of os.path.join(*parts)
|
||||
|
||||
Joins pathname components and ensures that with each join the result
|
||||
is a subdirectory of the previous join
|
||||
"""
|
||||
new = prev = ""
|
||||
for part in parts:
|
||||
new = os.path.normpath(os.path.join(prev, part))
|
||||
if len(new) <= len(prev) or prev != "" and not new.startswith(
|
||||
prev + os.path.sep):
|
||||
raise ValueError('path {0} is not allowed {1}'.format(
|
||||
os.path.join(*parts), parts))
|
||||
prev = new
|
||||
return new
|
|
@ -19,6 +19,7 @@ import sys
|
|||
import six
|
||||
import yaml
|
||||
|
||||
from murano.common.helpers import path
|
||||
from murano.packages import exceptions
|
||||
from murano.packages import package_base
|
||||
|
||||
|
@ -76,7 +77,8 @@ class HotPackage(package_base.PackageBase):
|
|||
return self._translated_class, '<generated code>'
|
||||
|
||||
def _translate_class(self):
|
||||
template_file = os.path.join(self._source_directory, 'template.yaml')
|
||||
template_file = path.secure_join(
|
||||
self._source_directory, 'template.yaml')
|
||||
|
||||
if not os.path.isfile(template_file):
|
||||
raise exceptions.PackageClassLoadError(
|
||||
|
@ -92,9 +94,8 @@ class HotPackage(package_base.PackageBase):
|
|||
'Extends': 'io.murano.Application'
|
||||
}
|
||||
|
||||
hot_envs_path = os.path.join(self._source_directory,
|
||||
RESOURCES_DIR_NAME,
|
||||
HOT_ENV_DIR_NAME)
|
||||
hot_envs_path = path.secure_join(
|
||||
self._source_directory, RESOURCES_DIR_NAME, HOT_ENV_DIR_NAME)
|
||||
|
||||
# if using hot environments, doing parameter validation with contracts
|
||||
# will overwrite the parameters in the hot environment.
|
||||
|
@ -190,9 +191,8 @@ class HotPackage(package_base.PackageBase):
|
|||
|
||||
@staticmethod
|
||||
def _translate_files(source_directory):
|
||||
hot_files_path = os.path.join(source_directory,
|
||||
RESOURCES_DIR_NAME,
|
||||
HOT_FILES_DIR_NAME)
|
||||
hot_files_path = path.secure_join(
|
||||
source_directory, RESOURCES_DIR_NAME, HOT_FILES_DIR_NAME)
|
||||
|
||||
return HotPackage._build_hot_resources(hot_files_path)
|
||||
|
||||
|
@ -202,7 +202,7 @@ class HotPackage(package_base.PackageBase):
|
|||
if os.path.isdir(basedir):
|
||||
for root, _, files in os.walk(os.path.abspath(basedir)):
|
||||
for f in files:
|
||||
full_path = os.path.join(root, f)
|
||||
full_path = path.secure_join(root, f)
|
||||
relative_path = os.path.relpath(full_path, basedir)
|
||||
result.append(relative_path)
|
||||
return result
|
||||
|
@ -517,7 +517,8 @@ class HotPackage(package_base.PackageBase):
|
|||
return app
|
||||
|
||||
def _translate_ui(self):
|
||||
template_file = os.path.join(self._source_directory, 'template.yaml')
|
||||
template_file = path.secure_join(
|
||||
self._source_directory, 'template.yaml')
|
||||
|
||||
if not os.path.isfile(template_file):
|
||||
raise exceptions.PackageClassLoadError(
|
||||
|
|
|
@ -22,6 +22,7 @@ import zipfile
|
|||
import six
|
||||
import yaml
|
||||
|
||||
from murano.common.helpers import path
|
||||
from murano.common.plugins import package_types_loader
|
||||
import murano.packages.exceptions as e
|
||||
import murano.packages.hot_package
|
||||
|
@ -76,14 +77,14 @@ def load_from_file(archive_path, target_dir=None, drop_dir=False):
|
|||
shutil.rmtree(target_dir)
|
||||
else:
|
||||
for f in os.listdir(target_dir):
|
||||
os.unlink(os.path.join(target_dir, f))
|
||||
os.unlink(path.secure_join(target_dir, f))
|
||||
|
||||
|
||||
def load_from_dir(source_directory, filename='manifest.yaml'):
|
||||
if not os.path.isdir(source_directory) or not os.path.exists(
|
||||
source_directory):
|
||||
raise e.PackageLoadError('Invalid package directory')
|
||||
full_path = os.path.join(source_directory, filename)
|
||||
full_path = path.secure_join(source_directory, filename)
|
||||
if not os.path.isfile(full_path):
|
||||
raise e.PackageLoadError('Unable to find package manifest')
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import os
|
||||
|
||||
from murano.common.helpers import path
|
||||
from murano.packages import exceptions
|
||||
from murano.packages import package_base
|
||||
|
||||
|
@ -34,7 +35,8 @@ class MuranoPlPackage(package_base.PackageBase):
|
|||
|
||||
@property
|
||||
def ui(self):
|
||||
full_path = os.path.join(self._source_directory, 'UI', self._ui_file)
|
||||
full_path = path.secure_join(
|
||||
self._source_directory, 'UI', self._ui_file)
|
||||
if not os.path.isfile(full_path):
|
||||
return None
|
||||
with open(full_path, 'rb') as stream:
|
||||
|
@ -49,7 +51,8 @@ class MuranoPlPackage(package_base.PackageBase):
|
|||
raise exceptions.PackageClassLoadError(
|
||||
name, 'Class not defined in package ' + self.full_name)
|
||||
def_file = self._classes[name]
|
||||
full_path = os.path.join(self._source_directory, 'Classes', def_file)
|
||||
full_path = path.secure_join(
|
||||
self._source_directory, 'Classes', def_file)
|
||||
if not os.path.isfile(full_path):
|
||||
raise exceptions.PackageClassLoadError(
|
||||
name, 'File with class definition not found')
|
||||
|
|
|
@ -20,6 +20,8 @@ import zipfile
|
|||
|
||||
import six
|
||||
|
||||
from murano.common.helpers import path
|
||||
|
||||
|
||||
class PackageType(object):
|
||||
Library = 'Library'
|
||||
|
@ -114,11 +116,11 @@ class Package(object):
|
|||
raise NotImplementedError()
|
||||
|
||||
|
||||
def _zip_dir(path, zip_file):
|
||||
for root, _, files in os.walk(path):
|
||||
def _zip_dir(base, zip_file):
|
||||
for root, _, files in os.walk(base):
|
||||
for f in files:
|
||||
abs_path = os.path.join(root, f)
|
||||
relative_path = os.path.relpath(abs_path, path)
|
||||
abs_path = path.secure_join(root, f)
|
||||
relative_path = os.path.relpath(abs_path, base)
|
||||
zip_file.write(abs_path, relative_path)
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import sys
|
|||
import semantic_version
|
||||
import six
|
||||
|
||||
from murano.common.helpers import path
|
||||
from murano.common.i18n import _
|
||||
from murano.packages import exceptions
|
||||
from murano.packages import package
|
||||
|
@ -119,13 +120,13 @@ class PackageBase(package.Package):
|
|||
self._supplier.get('Logo'), 'supplier_logo.png', 'supplier logo')
|
||||
|
||||
def get_resource(self, name):
|
||||
resources_dir = os.path.join(self._source_directory, 'Resources')
|
||||
resources_dir = path.secure_join(self._source_directory, 'Resources')
|
||||
if not os.path.exists(resources_dir):
|
||||
os.makedirs(resources_dir)
|
||||
return os.path.join(resources_dir, name)
|
||||
return path.secure_join(resources_dir, name)
|
||||
|
||||
def _load_image(self, file_name, default_name, what_image):
|
||||
full_path = os.path.join(
|
||||
full_path = path.secure_join(
|
||||
self._source_directory, file_name or default_name)
|
||||
if not os.path.isfile(full_path) and not file_name:
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue