Skip to content

Commit

Permalink
internal/appsec/dyngo: clear actions/events before second waf run
Browse files Browse the repository at this point in the history
  • Loading branch information
Hellzy committed Nov 17, 2022
1 parent dea3413 commit 464759f
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 9 deletions.
14 changes: 11 additions & 3 deletions internal/appsec/dyngo/instrumentation/common.go
Expand Up @@ -65,6 +65,12 @@ func (s *SecurityEventsHolder) Events() []json.RawMessage {
return s.events
}

func (s *SecurityEventsHolder) ClearEvents() {
s.mu.Lock()
defer s.mu.Unlock()
s.events = []json.RawMessage{}
}

// SetTags fills the span tags using the key/value pairs found in `tags`
func SetTags(span TagSetter, tags map[string]interface{}) {
for k, v := range tags {
Expand Down Expand Up @@ -102,9 +108,11 @@ func SetEventSpanTags(span TagSetter, events []json.RawMessage) error {

// Create the value of the security event tag.
// TODO(Julio-Guerra): a future libddwaf version should return something
// avoiding us the following events concatenation logic which currently
// involves unserializing the top-level JSON arrays to concatenate them
// together.
//
// avoiding us the following events concatenation logic which currently
// involves unserializing the top-level JSON arrays to concatenate them
// together.
//
// TODO(Julio-Guerra): avoid serializing the json in the request hot path
func makeEventTagValue(events []json.RawMessage) (json.RawMessage, error) {
var v interface{}
Expand Down
8 changes: 7 additions & 1 deletion internal/appsec/dyngo/instrumentation/httpsec/http.go
Expand Up @@ -80,7 +80,7 @@ func WrapHandler(handler http.Handler, span ddtrace.Span, pathParams map[string]
switch a := action.(type) {
case *BlockRequestAction:
handler = a.handler
op.AddTag("appsec.blocked", true)
op.AddTag(tagBlockedRequest, true)
default:
log.Warn("appsec: unsupported action %v. Ignoring.", a)
}
Expand All @@ -97,6 +97,8 @@ func WrapHandler(handler http.Handler, span ddtrace.Span, pathParams map[string]
events := op.Events()
if len(events) > 0 {
applyActions(op)
op.ClearEvents()
op.ClearActions()
}
defer func() {
var status int
Expand Down Expand Up @@ -214,6 +216,10 @@ func (op *Operation) Actions() []Action {
return op.actions
}

func (op *Operation) ClearActions() {
op.actions = []Action{}
}

// StartSDKBodyOperation starts the SDKBody operation and emits a start event
func StartSDKBodyOperation(parent *Operation, args SDKBodyOperationArgs) *SDKBodyOperation {
op := &SDKBodyOperation{Operation: dyngo.NewOperation(parent)}
Expand Down
8 changes: 5 additions & 3 deletions internal/appsec/dyngo/instrumentation/httpsec/tags.go
Expand Up @@ -21,9 +21,11 @@ import (
const (
// envClientIPHeader is the name of the env var used to specify the IP header to be used for client IP collection.
envClientIPHeader = "DD_TRACE_CLIENT_IP_HEADER"
// multipleIPHeaders sets the multiple ip header tag used internally to tell the backend an error occurred when
// tagMultipleIPHeaders sets the multiple ip header tag used internally to tell the backend an error occurred when
// retrieving an HTTP request client IP.
multipleIPHeaders = "_dd.multiple-ip-headers"
tagMultipleIPHeaders = "_dd.multiple-ip-headers"
// tagBlockedRequest used to convey whether a request is blocked
tagBlockedRequest = "appsec.blocked"
)

var (
Expand Down Expand Up @@ -138,7 +140,7 @@ func SetIPTags(span instrumentation.TagSetter, r *http.Request) {
for i := range ips {
span.SetTag(ext.HTTPRequestHeaders+"."+headers[i], ips[i])
}
span.SetTag(multipleIPHeaders, strings.Join(headers, ","))
span.SetTag(tagMultipleIPHeaders, strings.Join(headers, ","))
}
}

Expand Down
4 changes: 2 additions & 2 deletions internal/appsec/dyngo/instrumentation/httpsec/tags_test.go
Expand Up @@ -225,11 +225,11 @@ func TestIPHeaders(t *testing.T) {
SetIPTags(&span, &r)
if tc.expectedIP.IsValid() {
require.Equal(t, tc.expectedIP.String(), span.Tag(ext.HTTPClientIP))
require.Nil(t, span.Tag(multipleIPHeaders))
require.Nil(t, span.Tag(tagMultipleIPHeaders))
} else {
require.Nil(t, span.Tag(ext.HTTPClientIP))
if tc.multiHeaders != "" {
require.Equal(t, tc.multiHeaders, span.Tag(multipleIPHeaders))
require.Equal(t, tc.multiHeaders, span.Tag(tagMultipleIPHeaders))
for hdr, ip := range tc.headers {
require.Equal(t, ip, span.Tag(ext.HTTPRequestHeaders+"."+hdr))
}
Expand Down

0 comments on commit 464759f

Please sign in to comment.