Skip to content

Commit

Permalink
contrib/{echo,gorilla}: add AppSec response-status test (#1177)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hellzy committed Feb 25, 2022
1 parent 226f6a6 commit dd9c356
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 27 deletions.
20 changes: 20 additions & 0 deletions contrib/gorilla/mux/mux_test.go
Expand Up @@ -384,4 +384,24 @@ func TestAppSec(t *testing.T) {
require.True(t, strings.Contains(event, "myPathParam2"))
require.True(t, strings.Contains(event, "server.request.path_params"))
})

t.Run("response-status", func(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

req, err := http.NewRequest("POST", srv.URL+"/etc/", nil)
if err != nil {
panic(err)
}
res, err := srv.Client().Do(req)
require.NoError(t, err)
require.Equal(t, 404, res.StatusCode)

finished := mt.FinishedSpans()
require.Len(t, finished, 1)
event := finished[0].Tag("_dd.appsec.json").(string)
require.NotNil(t, event)
require.True(t, strings.Contains(event, "server.response.status"))
require.True(t, strings.Contains(event, "nfd-000-001"))
})
}
41 changes: 17 additions & 24 deletions contrib/labstack/echo.v4/appsec.go
Expand Up @@ -14,30 +14,23 @@ import (
"github.com/labstack/echo/v4"
)

func withAppSec(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
req := c.Request()
span, ok := tracer.SpanFromContext(req.Context())
if !ok {
return next(c)
}
httpsec.SetAppSecTags(span)
params := make(map[string]string)
for _, n := range c.ParamNames() {
params[n] = c.Param(n)
}
args := httpsec.MakeHandlerOperationArgs(req, params)
op := httpsec.StartOperation(args, nil)
defer func() {
events := op.Finish(httpsec.HandlerOperationRes{Status: c.Response().Status})
if len(events) > 0 {
remoteIP, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
remoteIP = req.RemoteAddr
}
httpsec.SetSecurityEventTags(span, events, remoteIP, args.Headers, c.Response().Writer.Header())
func useAppSec(c echo.Context, span tracer.Span) func() {
req := c.Request()
httpsec.SetAppSecTags(span)
params := make(map[string]string)
for _, n := range c.ParamNames() {
params[n] = c.Param(n)
}
args := httpsec.MakeHandlerOperationArgs(req, params)
op := httpsec.StartOperation(args, nil)
return func() {
events := op.Finish(httpsec.HandlerOperationRes{Status: c.Response().Status})
if len(events) > 0 {
remoteIP, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
remoteIP = req.RemoteAddr
}
}()
return next(c)
httpsec.SetSecurityEventTags(span, events, remoteIP, args.Headers, c.Response().Writer.Header())
}
}
}
8 changes: 5 additions & 3 deletions contrib/labstack/echo.v4/echotrace.go
Expand Up @@ -20,15 +20,13 @@ import (

// Middleware returns echo middleware which will trace incoming requests.
func Middleware(opts ...Option) echo.MiddlewareFunc {
appsecEnabled := appsec.Enabled()
cfg := new(config)
defaults(cfg)
for _, fn := range opts {
fn(cfg)
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
if appsec.Enabled() {
next = withAppSec(next)
}
return func(c echo.Context) error {
request := c.Request()
resource := request.Method + " " + c.Path()
Expand Down Expand Up @@ -57,6 +55,10 @@ func Middleware(opts ...Option) echo.MiddlewareFunc {
// pass the span through the request context
c.SetRequest(request.WithContext(ctx))
// serve the request to the next middleware
if appsecEnabled {
afterMiddleware := useAppSec(c, span)
defer afterMiddleware()
}
err := next(c)
if err != nil {
finishOpts = append(finishOpts, tracer.WithError(err))
Expand Down
20 changes: 20 additions & 0 deletions contrib/labstack/echo.v4/echotrace_test.go
Expand Up @@ -367,5 +367,25 @@ func TestAppSec(t *testing.T) {
require.False(t, strings.Contains(event, "myPathParam3"))
require.True(t, strings.Contains(event, "server.request.path_params"))
})

t.Run("response-status", func(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

req, err := http.NewRequest("POST", srv.URL+"/etc/", nil)
if err != nil {
panic(err)
}
res, err := srv.Client().Do(req)
require.NoError(t, err)
require.Equal(t, 404, res.StatusCode)

finished := mt.FinishedSpans()
require.Len(t, finished, 1)
event := finished[0].Tag("_dd.appsec.json").(string)
require.NotNil(t, event)
require.True(t, strings.Contains(event, "server.response.status"))
require.True(t, strings.Contains(event, "nfd-000-001"))
})
})
}

0 comments on commit dd9c356

Please sign in to comment.