Skip to content

Commit

Permalink
add conditional listener registration helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Eliott Bouhana <eliott.bouhana@datadoghq.com>
  • Loading branch information
eliottness committed Aug 9, 2024
1 parent 0a1ebb8 commit 104538f
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 17 deletions.
6 changes: 3 additions & 3 deletions internal/appsec/dyngo/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
// This is required because we really want to be able to log errors from dyngo
// but the log package depend on too much packages that we want to instrument.
// So we need to do this to avoid dependency cycles.
var LogError func(string, ...any)
var LogError = func(string, ...any) {}

// Operation interface type allowing to register event listeners to the
// operation. The event listeners will be automatically removed from the
Expand Down Expand Up @@ -321,7 +321,7 @@ func (b *dataBroadcaster) clear() {

func emitData[T any](b *dataBroadcaster, v T) {
defer func() {
if r := recover(); r != nil && LogError != nil {
if r := recover(); r != nil {
LogError("appsec: recovered from an unexpected panic from an event listener: %+v", r)
}
}()
Expand Down Expand Up @@ -352,7 +352,7 @@ func (r *eventRegister) clear() {

func emitEvent[O Operation, T any](r *eventRegister, op O, v T) {
defer func() {
if r := recover(); r != nil && LogError != nil {
if r := recover(); r != nil {
LogError("appsec: recovered from an unexpected panic from an event listener: %+v", r)
}
}()
Expand Down
4 changes: 2 additions & 2 deletions internal/appsec/listener/grpcsec/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ func (l *wafEventListener) onEvent(op *types.HandlerOperation, handlerArgs types
return
}

if l.isSecAddressListened(httpsec.ServerIoNetURLAddr) {
if httpsec.SSRFAddressesPresent(l.addresses) {
httpsec.RegisterRoundTripperListener(op, &op.SecurityEventsHolder, wafCtx, l.limiter)
}

if l.isSecAddressListened(ossec.ServerIOFSFileAddr) {
if ossec.OSAddressesPresent(l.addresses) {
ossec.RegisterOpenListener(op, &op.SecurityEventsHolder, wafCtx, l.limiter)
}

Expand Down
4 changes: 2 additions & 2 deletions internal/appsec/listener/httpsec/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ func (l *wafEventListener) onEvent(op *types.Operation, args types.HandlerOperat
return
}

if _, ok := l.addresses[ServerIoNetURLAddr]; ok {
if SSRFAddressesPresent(l.addresses) {
dyngo.On(op, shared.MakeWAFRunListener(&op.SecurityEventsHolder, wafCtx, l.limiter, func(args types.RoundTripOperationArgs) waf.RunAddressData {
return waf.RunAddressData{Ephemeral: map[string]any{ServerIoNetURLAddr: args.URL}}
}))
}

if _, ok := l.addresses[ossec.ServerIOFSFileAddr]; ok {
if ossec.OSAddressesPresent(l.addresses) {
ossec.RegisterOpenListener(op, &op.SecurityEventsHolder, wafCtx, l.limiter)
}

Expand Down
6 changes: 6 additions & 0 deletions internal/appsec/listener/httpsec/roundtripper.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package httpsec
import (
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec/types"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/sharedsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/trace"

Expand All @@ -21,3 +22,8 @@ func RegisterRoundTripperListener(op dyngo.Operation, events *trace.SecurityEven
return waf.RunAddressData{Ephemeral: map[string]any{ServerIoNetURLAddr: args.URL}}
}))
}

func SSRFAddressesPresent(addresses listener.AddressSet) bool {
_, urlAddr := addresses[ServerIoNetURLAddr]
return urlAddr
}
16 changes: 6 additions & 10 deletions internal/appsec/listener/ossec/lfi.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
package ossec

import (
"os"

"github.com/DataDog/appsec-internal-go/limiter"
waf "github.com/DataDog/go-libddwaf/v3"

"gopkg.in/DataDog/dd-trace-go.v1/appsec/events"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/ossec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/sharedsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/trace"
)
Expand All @@ -28,21 +27,18 @@ func RegisterOpenListener(op dyngo.Operation, eventsHolder *trace.SecurityEvents
})

dyngo.On(op, func(op *ossec.OpenOperation, args ossec.OpenOperationArgs) {
// We only care about read operations. We don't want to scan for write operations
// os.O_RDONLY is not a flag it's simply 0, so we can't do a simple bit mask
// If os.O_CREATE is set, we also want to monitor the operation because the file must not exist
if (args.Flags&os.O_RDWR == 0 && args.Flags != os.O_RDONLY) || args.Flags&os.O_CREATE != 0 {
return
}

dyngo.OnData(op, func(e *events.BlockingSecurityEvent) {
dyngo.OnFinish(op, func(op *ossec.OpenOperation, res ossec.OpenOperationRes) {
if res.Err != nil {
*res.Err = e
}
})
})

runWAF(op, args)
})
}

func OSAddressesPresent(addresses listener.AddressSet) bool {
_, fileAddr := addresses[ServerIOFSFileAddr]
return fileAddr
}

0 comments on commit 104538f

Please sign in to comment.