mirror of
https://github.com/ansible/awx.git
synced 2026-03-02 01:08:48 -03:30
Merge pull request #7584 from ryanpetrello/jinja2-sandbox
use jinja2.sandbox for credential type injectors Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -7,8 +7,8 @@ import json
|
|||||||
import re
|
import re
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import sandbox, StrictUndefined
|
||||||
from jinja2.exceptions import UndefinedError, TemplateSyntaxError
|
from jinja2.exceptions import UndefinedError, TemplateSyntaxError, SecurityError
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.contrib.postgres.fields import JSONField as upstream_JSONBField
|
from django.contrib.postgres.fields import JSONField as upstream_JSONBField
|
||||||
@@ -940,7 +940,7 @@ class CredentialTypeInjectorField(JSONSchemaField):
|
|||||||
self.validate_env_var_allowed(key)
|
self.validate_env_var_allowed(key)
|
||||||
for key, tmpl in injector.items():
|
for key, tmpl in injector.items():
|
||||||
try:
|
try:
|
||||||
Environment(
|
sandbox.ImmutableSandboxedEnvironment(
|
||||||
undefined=StrictUndefined
|
undefined=StrictUndefined
|
||||||
).from_string(tmpl).render(valid_namespace)
|
).from_string(tmpl).render(valid_namespace)
|
||||||
except UndefinedError as e:
|
except UndefinedError as e:
|
||||||
@@ -950,6 +950,10 @@ class CredentialTypeInjectorField(JSONSchemaField):
|
|||||||
code='invalid',
|
code='invalid',
|
||||||
params={'value': value},
|
params={'value': value},
|
||||||
)
|
)
|
||||||
|
except SecurityError as e:
|
||||||
|
raise django_exceptions.ValidationError(
|
||||||
|
_('Encountered unsafe code execution: {}').format(e)
|
||||||
|
)
|
||||||
except TemplateSyntaxError as e:
|
except TemplateSyntaxError as e:
|
||||||
raise django_exceptions.ValidationError(
|
raise django_exceptions.ValidationError(
|
||||||
_('Syntax error rendering template for {sub_key} inside of {type} ({error_msg})').format(
|
_('Syntax error rendering template for {sub_key} inside of {type} ({error_msg})').format(
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import tempfile
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
# Jinja2
|
# Jinja2
|
||||||
from jinja2 import Template
|
from jinja2 import sandbox
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -514,8 +514,11 @@ class CredentialType(CommonModelNameNotUnique):
|
|||||||
# If any file templates are provided, render the files and update the
|
# If any file templates are provided, render the files and update the
|
||||||
# special `tower` template namespace so the filename can be
|
# special `tower` template namespace so the filename can be
|
||||||
# referenced in other injectors
|
# referenced in other injectors
|
||||||
|
|
||||||
|
sandbox_env = sandbox.ImmutableSandboxedEnvironment()
|
||||||
|
|
||||||
for file_label, file_tmpl in file_tmpls.items():
|
for file_label, file_tmpl in file_tmpls.items():
|
||||||
data = Template(file_tmpl).render(**namespace)
|
data = sandbox_env.from_string(file_tmpl).render(**namespace)
|
||||||
_, path = tempfile.mkstemp(dir=private_data_dir)
|
_, path = tempfile.mkstemp(dir=private_data_dir)
|
||||||
with open(path, 'w') as f:
|
with open(path, 'w') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
@@ -537,14 +540,14 @@ class CredentialType(CommonModelNameNotUnique):
|
|||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
logger.error('Ignoring prohibited env var {}, reason: {}'.format(env_var, e))
|
logger.error('Ignoring prohibited env var {}, reason: {}'.format(env_var, e))
|
||||||
continue
|
continue
|
||||||
env[env_var] = Template(tmpl).render(**namespace)
|
env[env_var] = sandbox_env.from_string(tmpl).render(**namespace)
|
||||||
safe_env[env_var] = Template(tmpl).render(**safe_namespace)
|
safe_env[env_var] = sandbox_env.from_string(tmpl).render(**safe_namespace)
|
||||||
|
|
||||||
if 'INVENTORY_UPDATE_ID' not in env:
|
if 'INVENTORY_UPDATE_ID' not in env:
|
||||||
# awx-manage inventory_update does not support extra_vars via -e
|
# awx-manage inventory_update does not support extra_vars via -e
|
||||||
extra_vars = {}
|
extra_vars = {}
|
||||||
for var_name, tmpl in self.injectors.get('extra_vars', {}).items():
|
for var_name, tmpl in self.injectors.get('extra_vars', {}).items():
|
||||||
extra_vars[var_name] = Template(tmpl).render(**namespace)
|
extra_vars[var_name] = sandbox_env.from_string(tmpl).render(**namespace)
|
||||||
|
|
||||||
def build_extra_vars_file(vars, private_dir):
|
def build_extra_vars_file(vars, private_dir):
|
||||||
handle, path = tempfile.mkstemp(dir = private_dir)
|
handle, path = tempfile.mkstemp(dir = private_dir)
|
||||||
|
|||||||
Reference in New Issue
Block a user