fix(executor): always anchor custom regex patterns and harden shellAfterCompleted
Wrap regex: patterns in a non-capturing group before applying ^...$ so alternation cannot bypass full-string matching. Return template parse errors from buildShellAfterCommand, and guard nil binding/action before building shellAfterCompleted commands.
This commit is contained in:
parent
e421780c98
commit
1396184777
|
|
@ -385,7 +385,7 @@ func testWithEntity(t *testing.T, binding *executor.ActionBinding, rr *Dashboard
|
|||
assert.Equal(t, expectedCanExec, actionResult.CanExec, message)
|
||||
}
|
||||
|
||||
// buildExecWithoutLogsTestConfig returns config for GHSA-jm28: user "runner" may exec but not read logs.
|
||||
// buildExecWithoutLogsTestConfig returns config for GHSA-jm28-2wcr-qf3h: user "runner" may exec but not read logs.
|
||||
func buildExecWithoutLogsTestConfig(t *testing.T) (*config.Config, *authpublic.AuthenticatedUser) {
|
||||
t.Helper()
|
||||
cfg := config.DefaultConfig()
|
||||
|
|
|
|||
|
|
@ -315,10 +315,6 @@ func typeSafetyCheckDatetime(value string) error {
|
|||
}
|
||||
|
||||
func anchorCustomRegexPattern(pattern string) string {
|
||||
if strings.HasPrefix(pattern, "^") && strings.HasSuffix(pattern, "$") {
|
||||
return pattern
|
||||
}
|
||||
|
||||
return "^(?:" + pattern + ")$"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -596,6 +596,13 @@ func TestTypeSafetyCheckRegex(t *testing.T) {
|
|||
value: "example.com; id",
|
||||
hasError: true,
|
||||
},
|
||||
{
|
||||
name: "reject alternation bypass when pattern looks anchored",
|
||||
field: "host",
|
||||
pattern: "regex:^safe$|bad",
|
||||
value: "xxxbad",
|
||||
hasError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
|
|||
|
|
@ -1238,8 +1238,22 @@ func stepExecAfter(req *ExecutionRequest) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func buildShellAfterCommand(ctx context.Context, req *ExecutionRequest, stdout, stderr *bytes.Buffer) (*exec.Cmd, map[string]string, error) {
|
||||
func shellAfterCompletedAction(req *ExecutionRequest) (*config.Action, bool) {
|
||||
if req == nil {
|
||||
return nil, false
|
||||
}
|
||||
if !hasBindingAndAction(req) {
|
||||
return nil, false
|
||||
}
|
||||
if req.Binding.Action.ShellAfterCompleted == "" {
|
||||
return nil, false
|
||||
}
|
||||
return req.Binding.Action, true
|
||||
}
|
||||
|
||||
func buildShellAfterCommand(ctx context.Context, req *ExecutionRequest, stdout, stderr *bytes.Buffer) (*exec.Cmd, map[string]string, error) {
|
||||
action, ok := shellAfterCompletedAction(req)
|
||||
if !ok {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
|
|
@ -1248,14 +1262,14 @@ func buildShellAfterCommand(ctx context.Context, req *ExecutionRequest, stdout,
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
finalParsedCommand, err := tpl.ParseTemplateWithActionContext(req.Binding.Action.ShellAfterCompleted, req.Binding.Entity, args)
|
||||
finalParsedCommand, err := tpl.ParseTemplateWithActionContext(action.ShellAfterCompleted, req.Binding.Entity, args)
|
||||
if err != nil {
|
||||
msg := "Could not prepare shellAfterCompleted command: " + err.Error() + "\n"
|
||||
req.mutateLogEntry(func(entry *InternalLogEntry) {
|
||||
entry.Output += msg
|
||||
})
|
||||
log.Warn(msg)
|
||||
return nil, nil, nil
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cmd := wrapCommandInShell(ctx, finalParsedCommand)
|
||||
|
|
|
|||
Loading…
Reference in New Issue