client/template: configuration for function blacklist and sandboxing

When rendering a task template, the `plugin` function is no longer
permitted by default and will raise an error. An operator can opt-in
to permitting this function with the new `template.function_blacklist`
field in the client configuration.

When rendering a task template, path parameters for the `file`
function will be treated as relative to the task directory by
default. Relative paths or symlinks that point outside the task
directory will raise an error. An operator can opt-out of this
protection with the new `template.disable_file_sandbox` field in the
client configuration.
This commit is contained in:
Tim Gross
2019-08-02 15:20:14 -04:00
parent e4e7ca074d
commit ffb83e1ef1
7 changed files with 100 additions and 23 deletions

View File

@@ -545,11 +545,11 @@ func maskProcessEnv(env map[string]string) map[string]string {
// parseTemplateConfigs converts the tasks templates in the config into
// consul-templates
func parseTemplateConfigs(config *TaskTemplateManagerConfig) (map[ctconf.TemplateConfig]*structs.Template, error) {
func parseTemplateConfigs(config *TaskTemplateManagerConfig) (map[*ctconf.TemplateConfig]*structs.Template, error) {
allowAbs := config.ClientConfig.ReadBoolDefault(hostSrcOption, true)
taskEnv := config.EnvBuilder.Build()
ctmpls := make(map[ctconf.TemplateConfig]*structs.Template, len(config.Templates))
ctmpls := make(map[*ctconf.TemplateConfig]*structs.Template, len(config.Templates))
for _, tmpl := range config.Templates {
var src, dest string
if tmpl.SourcePath != "" {
@@ -573,6 +573,10 @@ func parseTemplateConfigs(config *TaskTemplateManagerConfig) (map[ctconf.Templat
ct.Contents = &tmpl.EmbeddedTmpl
ct.LeftDelim = &tmpl.LeftDelim
ct.RightDelim = &tmpl.RightDelim
ct.FunctionBlacklist = config.ClientConfig.TemplateConfig.FunctionBlacklist
if !config.ClientConfig.TemplateConfig.DisableSandbox {
ct.SandboxPath = &config.TaskDir
}
// Set the permissions
if tmpl.Perms != "" {
@@ -585,7 +589,7 @@ func parseTemplateConfigs(config *TaskTemplateManagerConfig) (map[ctconf.Templat
}
ct.Finalize()
ctmpls[*ct] = tmpl
ctmpls[ct] = tmpl
}
return ctmpls, nil
@@ -594,7 +598,7 @@ func parseTemplateConfigs(config *TaskTemplateManagerConfig) (map[ctconf.Templat
// newRunnerConfig returns a consul-template runner configuration, setting the
// Vault and Consul configurations based on the clients configs.
func newRunnerConfig(config *TaskTemplateManagerConfig,
templateMapping map[ctconf.TemplateConfig]*structs.Template) (*ctconf.Config, error) {
templateMapping map[*ctconf.TemplateConfig]*structs.Template) (*ctconf.Config, error) {
cc := config.ClientConfig
conf := ctconf.DefaultConfig()
@@ -603,7 +607,7 @@ func newRunnerConfig(config *TaskTemplateManagerConfig,
flat := ctconf.TemplateConfigs(make([]*ctconf.TemplateConfig, 0, len(templateMapping)))
for ctmpl := range templateMapping {
local := ctmpl
flat = append(flat, &local)
flat = append(flat, local)
}
conf.Templates = &flat

View File

@@ -125,8 +125,13 @@ func newTestHarness(t *testing.T, templates []*structs.Template, consul, vault b
mockHooks: NewMockTaskHooks(),
templates: templates,
node: mock.Node(),
config: &config.Config{Region: region},
emitRate: DefaultMaxTemplateEventRate,
config: &config.Config{
Region: region,
TemplateConfig: &config.ClientTemplateConfig{
FunctionBlacklist: []string{"plugin"},
DisableSandbox: false,
}},
emitRate: DefaultMaxTemplateEventRate,
}
// Build the task environment