Skip to content

Commit

Permalink
appsec: add examples & comments for MonitorParsedHTTPBody
Browse files Browse the repository at this point in the history
  • Loading branch information
Hellzy committed Feb 23, 2022
1 parent 170a553 commit 5823540
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
13 changes: 9 additions & 4 deletions appsec/appsec.go
Expand Up @@ -6,6 +6,8 @@
//go:build appsec
// +build appsec

// Package appsec provides application security features in the form of SDK
// functions that can be manually called to monitor specific code paths and data
package appsec

import (
Expand All @@ -14,10 +16,13 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/httpsec"
)

// MonitorParsedHTTPBody is an SDK solution for users to ask AppSec to perform rule matching on the parsed request body.
// `body`: the parsed body value to be used for rule matching.
// `ctx`: the context of the http.Request that for which the matching is to be performed.
// XXX: explain in details + add example
// MonitorParsedHTTPBody performs rule matching on the *parsed* HTTP request body.
// - body: the parsed HTTP body value to be used for rule matching.
// - ctx: the context of the http.Request for which the matching is to be performed.
// Note that some HTTP frameworks implement their own version of context.Context,
// however this function expects this exact type to be used.
// Also note that passing the HTTP request raw body instead of parsed will result
// in inaccurate attack detection
func MonitorParsedHTTPBody(ctx context.Context, body interface{}) {
httpsec.MonitorParsedBody(ctx, body)
}
50 changes: 50 additions & 0 deletions appsec/example_test.go
@@ -0,0 +1,50 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2022 Datadog, Inc.

package appsec_test

import (
"io"
"io/ioutil"
"net/http"

"github.com/labstack/echo/v4"

"gopkg.in/DataDog/dd-trace-go.v1/appsec"
echotrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/labstack/echo.v4"
httptrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http"
)

func customBodyParser(body io.ReadCloser) string {
b, err := ioutil.ReadAll(body)
if err != nil {
return "Ill formed http body"
}
return string(b)
}

// Monitor HTTP request parsed body
func ExampleMonitorParsedHTTPBody() {
mux := httptrace.NewServeMux()
mux.HandleFunc("/body", func(w http.ResponseWriter, r *http.Request) {
// Use the SDK to monitor the request's parsed body
appsec.MonitorParsedHTTPBody(r.Context(), customBodyParser(r.Body))
w.Write([]byte("Body monitored using AppSec SDK\n"))
})
http.ListenAndServe(":8080", mux)
}

// Monitor HTTP request parsed body with a framework customized context type
func ExampleMonitorParsedHTTPBodyCustomContext() {
r := echo.New()
r.Use(echotrace.Middleware())
r.POST("/body", func(c echo.Context) error {
// Use the SDK to monitor the request's parsed body
appsec.MonitorParsedHTTPBody(c.Request().Context(), customBodyParser(c.Request().Body))
return c.String(http.StatusOK, "Body monitored using AppSec SDK")
})

r.Start(":8080")
}
6 changes: 3 additions & 3 deletions internal/appsec/dyngo/instrumentation/httpsec/http.go
Expand Up @@ -13,14 +13,14 @@ package httpsec
import (
"context"
"encoding/json"
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
"net"
"net/http"
"reflect"
"strings"

"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo"
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
)

// Abstract HTTP handler operation definition.
Expand Down Expand Up @@ -57,7 +57,7 @@ type (

// MonitorParsedBody starts and finishes the SDK body operation.
func MonitorParsedBody(ctx context.Context, body interface{}) {
if parent := FromContext(ctx); parent != nil {
if parent := fromContext(ctx); parent != nil {
op := StartSDKBodyOperation(parent, SDKBodyOperationArgs{Body: body})
op.Finish()
} else {
Expand Down Expand Up @@ -151,7 +151,7 @@ func StartOperation(ctx context.Context, args HandlerOperationArgs) (context.Con
return newCtx, op
}

func FromContext(ctx context.Context) *Operation {
func fromContext(ctx context.Context) *Operation {
// Avoid a runtime panic in case of error by collecting the 2 return values
op, _ := ctx.Value(contextKey{}).(*Operation)
return op
Expand Down

0 comments on commit 5823540

Please sign in to comment.