diff --git a/pkg/protocols/http/request.go b/pkg/protocols/http/request.go index 3deed7f1..0202f20e 100644 --- a/pkg/protocols/http/request.go +++ b/pkg/protocols/http/request.go @@ -488,6 +488,35 @@ var errStopExecution = errors.New("stop execution due to unresolved variables") // executeRequest executes the actual generated request and returns error if occurred func (request *Request) executeRequest(input *contextargs.Context, generatedRequest *generatedRequest, previousEvent output.InternalEvent, hasInteractMatchers bool, callback protocols.OutputEventCallback, requestCount int) error { + outputEvent := output.InternalEvent{} + var event *output.InternalWrappedEvent + // event should never be nil as per existing logic + defer func() { + if event == nil { + event := &output.InternalWrappedEvent{ + InternalEvent: map[string]interface{}{ + "template-id": request.options.TemplateID, + "host": input.MetaInput.Input, + }, + } + if request.CompiledOperators != nil && request.CompiledOperators.HasDSL() { + event.InternalEvent = outputEvent + } + callback(event) + return + } + if event.InternalEvent == nil { + event.InternalEvent = outputEvent + } + // make sure templateId is never nil + if event.InternalEvent["template-id"] == nil { + event.InternalEvent["template-id"] = request.options.TemplateID + } + if event.InternalEvent["host"] == nil { + event.InternalEvent["host"] = input.MetaInput.Input + } + }() + request.setCustomHeaders(generatedRequest) // Try to evaluate any payloads before replacement @@ -688,7 +717,7 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ // In case of interactsh markers and request times out, still send // a callback event so in case we receive an interaction, correlation is possible. // Also, to log failed use-cases. - outputEvent := request.responseToDSLMap(&http.Response{}, input.MetaInput.Input, formedURL, convUtil.String(dumpedRequest), "", "", "", 0, generatedRequest.meta) + outputEvent = request.responseToDSLMap(&http.Response{}, input.MetaInput.Input, formedURL, convUtil.String(dumpedRequest), "", "", "", 0, generatedRequest.meta) if i := strings.LastIndex(hostname, ":"); i != -1 { hostname = hostname[:i] } @@ -698,12 +727,6 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ } else { outputEvent["ip"] = httpclientpool.Dialer.GetDialedIP(hostname) } - - event := &output.InternalWrappedEvent{} - if request.CompiledOperators != nil && request.CompiledOperators.HasDSL() { - event.InternalEvent = outputEvent - } - callback(event) return err } @@ -775,7 +798,7 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ } finalEvent := make(output.InternalEvent) - outputEvent := request.responseToDSLMap(respChain.Response(), input.MetaInput.Input, matchedURL, convUtil.String(dumpedRequest), respChain.FullResponse().String(), respChain.Body().String(), respChain.Headers().String(), duration, generatedRequest.meta) + outputEvent = request.responseToDSLMap(respChain.Response(), input.MetaInput.Input, matchedURL, convUtil.String(dumpedRequest), respChain.FullResponse().String(), respChain.Body().String(), respChain.Headers().String(), duration, generatedRequest.meta) // add response fields to template context and merge templatectx variables to output event request.options.AddTemplateVars(input.MetaInput, request.Type(), request.ID, outputEvent) if request.options.HasTemplateCtx(input.MetaInput) { @@ -813,7 +836,7 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ // prune signature internal values if any request.pruneSignatureInternalValues(generatedRequest.meta) - event := eventcreator.CreateEventWithAdditionalOptions(request, generators.MergeMaps(generatedRequest.dynamicValues, finalEvent), request.options.Options.Debug || request.options.Options.DebugResponse, func(internalWrappedEvent *output.InternalWrappedEvent) { + event = eventcreator.CreateEventWithAdditionalOptions(request, generators.MergeMaps(generatedRequest.dynamicValues, finalEvent), request.options.Options.Debug || request.options.Options.DebugResponse, func(internalWrappedEvent *output.InternalWrappedEvent) { internalWrappedEvent.OperatorsResult.PayloadValues = generatedRequest.meta }) if hasInteractMatchers { diff --git a/pkg/templates/cluster.go b/pkg/templates/cluster.go index 80507563..e404a3d2 100644 --- a/pkg/templates/cluster.go +++ b/pkg/templates/cluster.go @@ -252,6 +252,13 @@ func (e *ClusterExecuter) Execute(ctx *scan.ScanContext) (bool, error) { previous := make(map[string]interface{}) dynamicValues := make(map[string]interface{}) err := e.requests.ExecuteWithResults(inputItem, dynamicValues, previous, func(event *output.InternalWrappedEvent) { + if event == nil { + // unlikely but just in case + return + } + if event.InternalEvent == nil { + event.InternalEvent = make(map[string]interface{}) + } for _, operator := range e.operators { result, matched := operator.operator.Execute(event.InternalEvent, e.requests.Match, e.requests.Extract, e.options.Options.Debug || e.options.Options.DebugResponse) event.InternalEvent["template-id"] = operator.templateID