diff --git a/internal/appsec/testdata/fp.json b/internal/appsec/testdata/fp.json index 52af47f36c..c7f630caec 100644 --- a/internal/appsec/testdata/fp.json +++ b/internal/appsec/testdata/fp.json @@ -15,6 +15,7 @@ }, "conditions": [ { + "operator": "phrase_match", "parameters": { "inputs": [ { @@ -24,13 +25,62 @@ "list": [ "$globals" ] - }, - "operator": "phrase_match" + } } ], "transformers": [ "lowercase" ] + }, + { + "id": "9d50832c-200d-4b21-a050-61379f1a9af8", + "name": "Track users.login.failure on id-auth - /id/auth/v1/login", + "tags": { + "category": "business_logic", + "custom": "1", + "type": "users.login.failure" + }, + "conditions": [ + { + "operator": "phrase_match", + "parameters": { + "inputs": [ + { + "address": "server.request.uri.raw" + } + ], + "list": [ + "/id/auth/v1/login" + ] + } + }, + { + "operator": "phrase_match", + "parameters": { + "inputs": [ + { + "address": "server.request.method" + } + ], + "list": [ + "POST" + ] + } + }, + { + "operator": "phrase_match", + "parameters": { + "inputs": [ + { + "address": "server.response.status" + } + ], + "list": [ + "401" + ] + } + } + ] } ], "processors": [ diff --git a/internal/appsec/waf_test.go b/internal/appsec/waf_test.go index 7e169ffb7a..347d4f802c 100644 --- a/internal/appsec/waf_test.go +++ b/internal/appsec/waf_test.go @@ -31,6 +31,7 @@ import ( httptrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/mocktracer" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" + "gopkg.in/DataDog/dd-trace-go.v1/internal/appsec" "gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/config" "gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo" @@ -945,7 +946,7 @@ func TestAttackerFingerprinting(t *testing.T) { // Start and trace an HTTP server mux := httptrace.NewServeMux() - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { pAppsec.TrackUserLoginSuccessEvent( r.Context(), "toto", @@ -956,31 +957,58 @@ func TestAttackerFingerprinting(t *testing.T) { w.Write([]byte("Hello World!\n")) }) + + mux.HandleFunc("/id/auth/v1/login", func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(401) + }) + srv := httptest.NewServer(mux) defer srv.Close() - mt := mocktracer.Start() - defer mt.Stop() - req, err := http.NewRequest("POST", srv.URL+"/test?x=1", nil) - require.NoError(t, err) - req.AddCookie(&http.Cookie{Name: "cookie", Value: "value"}) - resp, err := srv.Client().Do(req) - require.NoError(t, err) - defer resp.Body.Close() + for _, tc := range []struct { + name string + url string + }{ + { + name: "SDK", + url: "/test?x=1", + }, + { + name: "WAF", + url: "/?x=$globals", + }, + { + name: "CustomRule", + url: "/id/auth/v1/login", + }, + } { + t.Run(tc.name, func(t *testing.T) { + mt := mocktracer.Start() + defer mt.Stop() - require.Len(t, mt.FinishedSpans(), 1) + req, err := http.NewRequest("POST", srv.URL+tc.url, nil) + require.NoError(t, err) + req.AddCookie(&http.Cookie{Name: "cookie", Value: "value"}) + resp, err := srv.Client().Do(req) + require.NoError(t, err) + defer resp.Body.Close() + + require.Len(t, mt.FinishedSpans(), 1) - tags := mt.FinishedSpans()[0].Tags() + tags := mt.FinishedSpans()[0].Tags() - require.Contains(t, tags, "_dd.appsec.fp.http.header") - require.Contains(t, tags, "_dd.appsec.fp.http.endpoint") - require.Contains(t, tags, "_dd.appsec.fp.http.network") - require.Contains(t, tags, "_dd.appsec.fp.session") + require.Contains(t, tags, "_dd.appsec.fp.http.header") + require.Contains(t, tags, "_dd.appsec.fp.http.endpoint") + require.Contains(t, tags, "_dd.appsec.fp.http.network") + require.Contains(t, tags, "_dd.appsec.fp.session") - require.Regexp(t, `^hdr-`, tags["_dd.appsec.fp.http.header"]) - require.Regexp(t, `^http-`, tags["_dd.appsec.fp.http.endpoint"]) - require.Regexp(t, `^ssn-`, tags["_dd.appsec.fp.session"]) - require.Regexp(t, `^net-`, tags["_dd.appsec.fp.http.network"]) + require.Regexp(t, `^hdr-`, tags["_dd.appsec.fp.http.header"]) + require.Regexp(t, `^http-`, tags["_dd.appsec.fp.http.endpoint"]) + require.Regexp(t, `^ssn-`, tags["_dd.appsec.fp.session"]) + require.Regexp(t, `^net-`, tags["_dd.appsec.fp.http.network"]) + }) + + } } func init() {