Load template files only from their known source

Modify get_class to ensure that user-defined resources cannot result in
reads from the local filesystem. Only resources defined by the operator
in the global environment should read local files.

Change-Id: I845e7d23c73242a4a4c9c40599690ab705c75caa
Closes-Bug: #1496277
This commit is contained in:
Zane Bitter 2016-01-11 18:43:43 -05:00
parent 336f0f8f34
commit 26e6d5f6d7
3 changed files with 17 additions and 13 deletions

View File

@ -156,10 +156,19 @@ class TemplateResourceInfo(ResourceInfo):
def get_class(self, files=None):
from heat.engine.resources import template_resource
if files and self.template_name in files:
data = files[self.template_name]
else:
if self.user_resource:
allowed_schemes = template_resource.REMOTE_SCHEMES
else:
allowed_schemes = template_resource.LOCAL_SCHEMES
data = template_resource.TemplateResource.get_template_file(
self.template_name,
allowed_schemes)
env = self.registry.environment
return template_resource.generate_class(str(self.name),
self.template_name,
env, files=files)
return template_resource.generate_class_from_template(str(self.name),
data, env)
def get_class_to_instantiate(self):
from heat.engine.resources import template_resource

View File

@ -31,15 +31,6 @@ REMOTE_SCHEMES = ('http', 'https')
LOCAL_SCHEMES = ('file',)
def generate_class(name, template_name, env, files=None):
data = None
if files is not None:
data = files.get(template_name)
if data is None:
data = TemplateResource.get_template_file(template_name, LOCAL_SCHEMES)
return generate_class_from_template(name, data, env)
def generate_class_from_template(name, data, env):
tmpl = template.Template(template_format.parse(data))
props, attrs = TemplateResource.get_schemas(tmpl, env.param_defaults)

View File

@ -665,7 +665,11 @@ class ProviderTemplateTest(common.HeatTestCase):
env_str = {'resource_registry': {'resources': {'fred': {
"OS::ResourceType": test_templ_name}}}}
env = environment.Environment(env_str)
global_env = environment.Environment({}, user_env=False)
global_env.load(env_str)
with mock.patch('heat.engine.resources._environment',
global_env):
env = environment.Environment({})
cls = env.get_class('OS::ResourceType', 'fred')
self.assertNotEqual(template_resource.TemplateResource, cls)
self.assertTrue(issubclass(cls, template_resource.TemplateResource))