Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(code): do NOT compile single code protocol w/o request.SelfContained #5757

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
1 change: 1 addition & 0 deletions integration_tests/protocols/code/ps1-snippet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ info:
description: |
ps1-code-snippet

self-contained: true
code:
- engine:
- powershell
Expand Down
1 change: 1 addition & 0 deletions integration_tests/protocols/code/py-env-var.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ info:
description: |
py-code-snippet

self-contained: true
code:
- engine:
- py
Expand Down
1 change: 1 addition & 0 deletions integration_tests/protocols/code/py-file.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ info:
description: |
py-file

self-contained: true
code:
- engine:
- py
Expand Down
1 change: 1 addition & 0 deletions integration_tests/protocols/code/py-interactsh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ info:
description: |
testcode

self-contained: true
variables:
i: "{{interactsh-url}}"

Expand Down
1 change: 1 addition & 0 deletions integration_tests/protocols/code/py-nosig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ info:
description: |
Python code without signature

self-contained: true
code:
- engine:
- py
Expand Down
1 change: 1 addition & 0 deletions integration_tests/protocols/code/py-snippet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ info:
description: |
py-code-snippet

self-contained: true
code:
- engine:
- py
Expand Down
1 change: 1 addition & 0 deletions integration_tests/protocols/code/unsigned.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ info:
description: |
unsigned-code-snippet

self-contained: true
code:
- engine:
- py
Expand Down
10 changes: 9 additions & 1 deletion pkg/protocols/code/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ var (
ErrCodeExecutionDeadline = errkit.New("code execution deadline exceeded").SetKind(errkit.ErrKindDeadline).Build()
)

// Request is a request for the SSL protocol
// Request is a request for the code protocol
type Request struct {
// Operators for the current request go here.
operators.Operators `yaml:",inline,omitempty"`
Expand All @@ -70,6 +70,9 @@ type Request struct {
// description: |
// Source File/Snippet
Source string `yaml:"source,omitempty" json:"source,omitempty" jsonschema:"title=source file/snippet,description=Source snippet"`
// description: |
// SelfContained specifies if the request is self-contained.
SelfContained bool `yaml:"-" json:"-"`

options *protocols.ExecutorOptions `yaml:"-" json:"-"`
preConditionCompiled *goja.Program `yaml:"-" json:"-"`
Expand Down Expand Up @@ -136,6 +139,11 @@ func (request *Request) Compile(options *protocols.ExecutorOptions) error {
}
request.preConditionCompiled = preConditionCompiled
}

if !request.options.IsMultiProtocol && !request.SelfContained {
return errorutil.NewWithTag(request.TemplateID, "could not compile single %q protocol without enabling self-contained", request.Type())
}

return nil
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/protocols/code/code_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ func TestCodeProtocol(t *testing.T) {
testutils.Init(options)
templateID := "testing-code"
request := &Request{
Engine: []string{"sh"},
Source: "echo test",
SelfContained: true,
Engine: []string{"sh"},
Source: "echo test",
}
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Expand Down
15 changes: 10 additions & 5 deletions pkg/templates/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ func (template *Template) parseSelfContainedRequests() {
for _, request := range template.RequestsHeadless {
request.SelfContained = true
}
for _, request := range template.RequestsCode {
request.SelfContained = true
}
}

// Requests returns the total request count for the template
Expand Down Expand Up @@ -178,11 +181,12 @@ func (template *Template) compileProtocolRequests(options *protocols.ExecutorOpt

var requests []protocols.Request

if template.hasMultipleRequests() {
// when multiple requests are present preserve the order of requests and protocols
// which is already done during unmarshalling
// when multiple requests or protocols are present, preserve the
// order of requests and protocols which already done during the
// unmarshalling process or else.
if template.hasMultipleRequests() || template.hasMultipleProtocols() {
requests = template.RequestsQueue
if options.Flow == "" {
if template.hasMultipleProtocols() && options.Flow == "" {
options.IsMultiProtocol = true
}
} else {
Expand Down Expand Up @@ -430,6 +434,8 @@ func parseTemplate(data []byte, options protocols.ExecutorOptions) (*Template, e
return nil, err
}

template.parseSelfContainedRequests()

if template.Executer != nil {
if err := template.Executer.Compile(); err != nil {
return nil, errors.Wrap(err, "could not compile request")
Expand All @@ -439,7 +445,6 @@ func parseTemplate(data []byte, options protocols.ExecutorOptions) (*Template, e
if template.Executer == nil && template.CompiledWorkflow == nil {
return nil, ErrCreateTemplateExecutor
}
template.parseSelfContainedRequests()

// check if the template is verified
// only valid templates can be verified or signed
Expand Down
34 changes: 34 additions & 0 deletions pkg/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,40 @@ func (template *Template) addRequestsToQueue(keys ...string) {
}
}

// hasMultipleProtocols checks if the template has multiple protocols
func (template *Template) hasMultipleProtocols() bool {
// TODO(dwisiswant0): This should be done using something like
// `Template.GetAllProtocolRequests` method, which returns
// a slice of anything that starts off with "Requests" for
// currently supported protocols - to avoid redundancy and
// keeps it future-proof.
protocolRequests := []int{
len(template.RequestsCode),
len(template.RequestsDNS),
len(template.RequestsFile),
len(template.RequestsHeadless),
len(template.RequestsHTTP),
len(template.RequestsJavascript),
len(template.RequestsNetwork),
len(template.RequestsSSL),
len(template.RequestsWebsocket),
len(template.RequestsWHOIS),
}

var protocolCount int
for _, count := range protocolRequests {
if count > 0 {
protocolCount++
}

if protocolCount > 1 {
return true
}
}

return false
}

// hasMultipleRequests checks if the template has multiple requests
// if so it preserves the order of the request during compile and execution
func (template *Template) hasMultipleRequests() bool {
Expand Down
Loading