Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal/appsec: add new AppSec beta functionality and support for contrib/net/http #1007

Merged
merged 113 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from 98 commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
9867d8f
appsec/dyngo: add an instrumentation gateway draft
Julio-Guerra Jul 26, 2021
08e0cd7
appsec: waf prototype as an operation event listener
Julio-Guerra Jul 27, 2021
29f5a0a
appsec/waf: simply the WAF event listener
Julio-Guerra Jul 27, 2021
cf61756
contrib/net/http: integrate an http handler operation
Julio-Guerra Jul 27, 2021
d13939a
appsec/dyngo: make the event register map key type safe
Julio-Guerra Sep 1, 2021
db0d47e
appsec: milestone 0
Julio-Guerra Sep 15, 2021
16573e6
httputil: add HTTP handler operation definition
Julio-Guerra Sep 15, 2021
51d8095
ddtrace/tracer: AppSec integration
Julio-Guerra Sep 15, 2021
2259fa6
ddtrace/tracer: fix unsafe condition in appsec stopping
Julio-Guerra Sep 15, 2021
cbbd178
Move appsec into dd-trace-go module's internal package
Julio-Guerra Sep 17, 2021
0a132f0
tracer: pass app version and env to the appsec config
Julio-Guerra Sep 17, 2021
33eb8c5
tracer: fix appsec stopping
Julio-Guerra Sep 20, 2021
5258dd5
appsec: remove the global context
Julio-Guerra Sep 20, 2021
06480b3
tracer: start appsec before the tracer is made global
Julio-Guerra Sep 20, 2021
0d94e93
appsec,dyngo: add copyright headers
Julio-Guerra Sep 20, 2021
6824cad
go.mod: add new appsec dependencies
Julio-Guerra Sep 20, 2021
ceb207c
Merge remote-tracking branch 'origin/appsec' into julio-guerra-appsec…
Julio-Guerra Sep 20, 2021
35d1e35
contrib/net/http: fix example imports
Julio-Guerra Sep 20, 2021
335156f
internal/dyngo: simplify the unregistration API
Julio-Guerra Sep 20, 2021
48d4454
dyngo: add run time type-checking of operations and listeners
Julio-Guerra Sep 22, 2021
518795c
dyngo: code simplification
Julio-Guerra Sep 22, 2021
6594153
dyngo: port event listeners to static types
Julio-Guerra Sep 27, 2021
caa3036
appsec,dyngo: fix golint errors
Julio-Guerra Sep 28, 2021
910c41d
appsec: fix goimports errors
Julio-Guerra Sep 28, 2021
c58f1c8
dyngo: fix code duplication mistake
Julio-Guerra Sep 28, 2021
e39d05a
go.mod: update go-libsqreen to v0.7.3 fixing a macos build issue
Julio-Guerra Sep 28, 2021
3e4b189
ddtrace,appsec: simplify the appsec integration into ddtrace
Julio-Guerra Sep 28, 2021
c7fd172
appsec: remove no longer used logger interface
Julio-Guerra Sep 28, 2021
8a6dba0
dyngo: merge eventManager into Operation
Julio-Guerra Sep 28, 2021
4757b74
dyngo: fix missing comments
Julio-Guerra Sep 28, 2021
f4302b1
dyngo: add missing import
Julio-Guerra Sep 28, 2021
0d81f3e
dyngo: optimize listeners removal
Julio-Guerra Sep 28, 2021
27a664b
dyngo: add a concurrency test
Julio-Guerra Sep 29, 2021
6777607
contrib/httputil: listen for security events sooner
Julio-Guerra Sep 29, 2021
1d34682
appsec: simplify the integration into the tracer thanks to Start() an…
Julio-Guerra Sep 29, 2021
1f5b0e4
appsec/waf: simplify to the least amount of necessary things
Julio-Guerra Oct 1, 2021
c14d17e
appsec: always use the tracer hostname and service name configuration
Julio-Guerra Oct 1, 2021
75a067c
dyngo: recover from any listener panics
Julio-Guerra Oct 4, 2021
18d671a
dyngo: remove the data event
Julio-Guerra Oct 6, 2021
1f22e7e
dyngo: simplified and (mostly) statically typed API
Julio-Guerra Oct 6, 2021
de6ee79
appsec: simplify the waf event listener registration
Julio-Guerra Oct 6, 2021
bfd4c32
appsec/waf: add libddwaf v1.0.12 bindings
Julio-Guerra Oct 8, 2021
fce1f33
appsec/waf/bindings: fix macos -l ldflag
Julio-Guerra Oct 8, 2021
6290a22
appsec/waf/bindings: fix macos -L ldflag
Julio-Guerra Oct 8, 2021
faa976c
appsec/waf/bindings: fix timeout type on macos
Julio-Guerra Oct 8, 2021
2e5f0a9
appsec/intake/client: fix flaky test
Julio-Guerra Oct 8, 2021
f687f92
appsec/waf/bindings: fix macos type errors
Julio-Guerra Oct 8, 2021
ca16d2b
appsec/intake/client: fix test assertion
Julio-Guerra Oct 8, 2021
60c5bc7
appsec/waf/bindings: fix macos type errors
Julio-Guerra Oct 8, 2021
33c8221
appsec/intake/client: fix test assertion
Julio-Guerra Oct 8, 2021
93c3916
appsec/intake/client: remove flaky condition
Julio-Guerra Oct 8, 2021
856f1de
appsec/waf: encode byte slices as strings
Julio-Guerra Oct 10, 2021
717b7dd
appsec: add support for dd_appsec_rules
Julio-Guerra Oct 10, 2021
9ce7dc5
appsec: milestone 1 compliance
Julio-Guerra Oct 10, 2021
402a30f
appsec/intake/api: removed unnecessary blocked field from the sec event
Julio-Guerra Oct 11, 2021
11c77d7
appsec/intake/api: make private things private
Julio-Guerra Oct 11, 2021
1f4b374
dyngo: synplify the package organization and port the tests to the ne…
Julio-Guerra Oct 11, 2021
2b47dfc
dyngo/httpinstr: fix server.request.cookies value
Julio-Guerra Oct 12, 2021
3e5c271
appsec/intake/api: enforce static typing of events for now
Julio-Guerra Oct 12, 2021
95394f6
ddtrace/tracer: fix appsec http client and agent url
Julio-Guerra Oct 12, 2021
23265e9
contrib/httputils: expose the monitored response status code
Julio-Guerra Oct 12, 2021
7625a5a
appsec: disable appsec by default at compilation time
Julio-Guerra Oct 12, 2021
93e07f2
appsec/waf: dynamically get the list of addresses to use at run time
Julio-Guerra Oct 13, 2021
d52e5e5
repo: update the 3rd party license file
Julio-Guerra Oct 13, 2021
b117934
appsec/waf: remove the build tag without_ddwaf in favor of the new ap…
Julio-Guerra Oct 13, 2021
1e834ae
appsec: move to ioutil.ReadFile to support older go versions
Julio-Guerra Oct 13, 2021
a1df977
appsec: add debug logs on sendbatch
Julio-Guerra Oct 13, 2021
0fa57fa
appsec/waf: update libddwaf to v1.0.13 to use the latest recommended …
Julio-Guerra Oct 13, 2021
b6636b7
appsec: better logs
Julio-Guerra Oct 13, 2021
1bf3ebf
appsec: fix tags configuration
Julio-Guerra Oct 13, 2021
cf04894
appsec/intake/api: fix url query parameters type
Julio-Guerra Oct 13, 2021
0f2a70e
appsec/waf: move the cgo bindings in the waf package
Julio-Guerra Oct 14, 2021
a31a25b
appsec: fix the service entry span tags
Julio-Guerra Oct 14, 2021
fbb8ed2
appsec/waf: fix disabled build tags
Julio-Guerra Oct 14, 2021
ca9c12c
appsec/waf: fix disabled build tags
Julio-Guerra Oct 14, 2021
9ffa1a5
appsec: make the intake api package a leaf package
Julio-Guerra Oct 14, 2021
ee74c4f
ci: try changing the version to 2.1
Julio-Guerra Oct 14, 2021
593a4dd
ci: try fixing job name
Julio-Guerra Oct 14, 2021
efb668c
ci: try adding parameters to test-contrib
Julio-Guerra Oct 14, 2021
d382449
appsec: fix broken tests
Julio-Guerra Oct 14, 2021
00d235c
dyngo: fix concurrency test
Julio-Guerra Oct 14, 2021
6a3c50f
appsec/waf: fix missing libunwind symbols on the linux build
Julio-Guerra Oct 15, 2021
7fceb97
appsec/tests: derease execution time
Julio-Guerra Oct 15, 2021
8869086
appsec/tests: try avoid the timeout
Julio-Guerra Oct 15, 2021
a677017
appsec: overall package simplification
Julio-Guerra Oct 15, 2021
8b11e2b
tracer/config: add an http client getter
Julio-Guerra Oct 15, 2021
74013a1
circleci: add appsec tests
Julio-Guerra Oct 15, 2021
ea26d3c
tracer: disable appsec on TestTracerCleanStop
Julio-Guerra Oct 15, 2021
5716ebe
appsec,dyngo: adapt test names to the style guide
Julio-Guerra Oct 15, 2021
eca35ec
appsec/waf: fix case where no attacks were performed
Julio-Guerra Oct 18, 2021
d8c281b
appsec/intake/api: add required blocked field
Julio-Guerra Oct 18, 2021
04badb2
appsec: fix number of sent events debug log
Julio-Guerra Oct 18, 2021
49938d7
appsec: refactor into a flat package
Julio-Guerra Oct 18, 2021
259db1a
dyngo: move package into appsec/
Julio-Guerra Oct 18, 2021
c42784f
appsec: fix golint missing comments
Julio-Guerra Oct 18, 2021
00c1f6c
appsec/rule: update to the latest version of recommended rules
Julio-Guerra Oct 18, 2021
0fff92b
appsec,contrib/httputils: fix gofmt errors
Julio-Guerra Oct 18, 2021
3de60f3
appsec/waf: add a readme telling where the libs come from
Julio-Guerra Oct 18, 2021
9f9094e
circleci: try better job names
Julio-Guerra Oct 19, 2021
b88b13c
circleci: try better job names
Julio-Guerra Oct 19, 2021
c5ea49e
appsec/httpinstr: remove os.Getenv lookup in WrapHandler
Julio-Guerra Oct 19, 2021
56a06f9
ddtrace: disable appsec for tests checking the logs
Julio-Guerra Oct 19, 2021
fd40cbe
circleci: adapt dd_appsec_enabled env var to new job param
Julio-Guerra Oct 19, 2021
95191af
circleci: adapt dd_appsec_enabled env var to new job param
Julio-Guerra Oct 19, 2021
15dcd90
circleci: adapt dd_appsec_enabled env var to new job param
Julio-Guerra Oct 19, 2021
8e9d199
circleci: adapt dd_appsec_enabled env var to new job param
Julio-Guerra Oct 19, 2021
6c61a52
ci: run dd-trace-go tests
Julio-Guerra Oct 19, 2021
420cd91
circleci: run test-contrib and go1_12-build with appsec
Julio-Guerra Oct 19, 2021
d3d0a16
circleci: run test-contrib and go1_12-build with appsec
Julio-Guerra Oct 19, 2021
66300c8
appsec: fix manual keep span tag on security event
Julio-Guerra Oct 19, 2021
5960329
Merge remote-tracking branch 'origin/v1' into julio-guerra-appsec/waf
Julio-Guerra Oct 19, 2021
7e37f52
circleci: fix whitespaces
Julio-Guerra Oct 19, 2021
67924a4
ddtrace/tracer: increase TestWorker timeout to 2 seconds
Julio-Guerra Oct 20, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 2
version: 2.1

plain-go114: &plain-go114
working_directory: /home/circleci/dd-trace-go.v1
Expand All @@ -8,7 +8,7 @@ plain-go114: &plain-go114
GOPATH: "/home/circleci/go"

jobs:
go1.12-build:
go1_12-build:
# Validate that the core builds with go1.12
docker:
- image: circleci/golang:1.12
Expand All @@ -21,7 +21,7 @@ jobs:
- run:
name: build
command: |
go build ./ddtrace/... ./profiler/...
go build ./ddtrace/... ./profiler/... ./internal/appsec

metadata:
<<: *plain-go114
Expand Down Expand Up @@ -79,9 +79,15 @@ jobs:


test-core:
parameters:
appsec:
description: "compile and enable appsec"
default: false
type: boolean
resource_class: xlarge
environment: # environment variables for the build itself
TEST_RESULTS: /tmp/test-results # path to where test results will be saved
DD_APPSEC_ENABLED: << parameters.appsec >>
<<: *plain-go114

steps:
Expand All @@ -94,7 +100,7 @@ jobs:
name: Testing
command: |
PACKAGE_NAMES=$(go list ./... | grep -v /contrib/ | circleci tests split --split-by=timings --timings-type=classname)
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES -v -race -coverprofile=coverage.txt -covermode=atomic
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES -v <<# parameters.appsec >>-tags appsec<</ parameters.appsec >> -race -coverprofile=coverage.txt -covermode=atomic

- save_cache:
key: go-mod-v4-{{ checksum "go.sum" }}
Expand Down Expand Up @@ -282,8 +288,11 @@ workflows:
version: 2
build-and-test:
jobs:
- go1.12-build
- go1_12-build
- metadata
- lint
- test-core
- test-core:
Julio-Guerra marked this conversation as resolved.
Show resolved Hide resolved
matrix:
parameters:
appsec: [ true, false ]
Julio-Guerra marked this conversation as resolved.
Show resolved Hide resolved
- test-contrib
3 changes: 2 additions & 1 deletion LICENSE-3rdparty.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Component,Origin,License,Copyright
import,io.opentracing,Apache-2.0,Copyright 2016-2017 The OpenTracing Authors
import,io.opentracing,Apache-2.0,Copyright 2016-2017 The OpenTracing Authors
appsec,https://github.com/DataDog/libddwaf,Apache-2.0 OR BSD-3-Clause,Copyright (c) 2021 Datadog <[email protected]>
19 changes: 15 additions & 4 deletions contrib/internal/httputil/make_responsewriter.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions contrib/internal/httputil/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/httpinstr"
)

// TraceConfig defines the configuration for request tracing.
Expand Down Expand Up @@ -53,8 +54,7 @@ func TraceAndServe(h http.Handler, cfg *TraceConfig) {
defer span.Finish(cfg.FinishOpts...)

cfg.ResponseWriter = wrapResponseWriter(cfg.ResponseWriter, span)

h.ServeHTTP(cfg.ResponseWriter, cfg.Request.WithContext(ctx))
httpinstr.WrapHandler(h, span).ServeHTTP(cfg.ResponseWriter, cfg.Request.WithContext(ctx))
Julio-Guerra marked this conversation as resolved.
Show resolved Hide resolved
}

// responseWriter is a small wrapper around an http response writer that will
Expand All @@ -69,8 +69,13 @@ func newResponseWriter(w http.ResponseWriter, span ddtrace.Span) *responseWriter
return &responseWriter{w, span, 0}
}

// Status returns the status code that was monitored.
func (w *responseWriter) Status() int {
return w.status
}

// Write writes the data to the connection as part of an HTTP reply.
// We explicitely call WriteHeader with the 200 status code
// We explicitly call WriteHeader with the 200 status code
// in order to get it reported into the span.
func (w *responseWriter) Write(b []byte) (int, error) {
if w.status == 0 {
Expand Down
66 changes: 35 additions & 31 deletions contrib/internal/httputil/trace_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion ddtrace/tracer/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ func (c *config) HasFeature(f string) bool {
return ok
}

// client returns the HTTP client to use.
func (c *config) client() *http.Client {
if c.httpClient == nil {
return defaultClient
}
return c.httpClient
}

// StartOption represents a function that can be provided as a parameter to Start.
type StartOption func(*config)

Expand Down Expand Up @@ -215,7 +223,7 @@ func newConfig(opts ...StartOption) *config {
}
}
if c.transport == nil {
c.transport = newHTTPTransport(c.agentAddr, c.httpClient)
c.transport = newHTTPTransport(c.agentAddr, c.client())
}
if c.propagator == nil {
c.propagator = NewPropagator(nil)
Expand Down
10 changes: 10 additions & 0 deletions ddtrace/tracer/option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package tracer

import (
"math"
"net/http"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -38,6 +39,15 @@ func TestTracerOptionsDefaults(t *testing.T) {
assert.Equal("localhost:8126", c.agentAddr)
assert.Equal("localhost:8125", c.dogstatsdAddr)
assert.Nil(nil, c.httpClient)
assert.Equal(defaultClient, c.client())
})

t.Run("http-client", func(t *testing.T) {
c := newConfig()
assert.Equal(t, defaultClient, c.client())
client := &http.Client{}
WithHTTPClient(client)(c)
assert.Equal(t, client, c.client())
})

t.Run("analytics", func(t *testing.T) {
Expand Down
15 changes: 15 additions & 0 deletions ddtrace/tracer/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/internal"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"
)

var _ ddtrace.Tracer = (*tracer)(nil)
Expand Down Expand Up @@ -213,6 +215,18 @@ func newTracer(opts ...StartOption) *tracer {
t.reportHealthMetrics(statsInterval)
}()
t.stats.Start()
appsec.Start(&appsec.Config{
Client: c.client(),
Version: version.Tag,
AgentURL: fmt.Sprintf("http://%s/", resolveAddr(c.agentAddr)),
Hostname: c.hostname,
Service: appsec.ServiceConfig{
Name: c.serviceName,
Version: c.version,
Environment: c.env,
},
Tags: c.globalTags,
})
Julio-Guerra marked this conversation as resolved.
Show resolved Hide resolved
return t
}

Expand Down Expand Up @@ -464,6 +478,7 @@ func (t *tracer) Stop() {
t.wg.Wait()
t.traceWriter.stop()
t.config.statsd.Close()
appsec.Stop()
}

// Inject uses the configured or default TextMap Propagator.
Expand Down
6 changes: 6 additions & 0 deletions ddtrace/tracer/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ func TestTracerCleanStop(t *testing.T) {
if testing.Short() {
return
}
// Avoid CI timeouts due to AppSec slowing down this test due to its init
// time.
if old := os.Getenv("DD_APPSEC_ENABLED"); old != "" {
os.Unsetenv("DD_APPSEC_ENABLED")
defer os.Setenv("DD_APPSEC_ENABLED", old)
}
Julio-Guerra marked this conversation as resolved.
Show resolved Hide resolved
os.Setenv("DD_TRACE_STARTUP_LOGS", "0")
defer os.Unsetenv("DD_TRACE_STARTUP_LOGS")

Expand Down
3 changes: 0 additions & 3 deletions ddtrace/tracer/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@ type httpTransport struct {
// otherwise needing to customize the transport layer, for instance when using
// a unix domain socket.
func newHTTPTransport(addr string, client *http.Client) *httpTransport {
if client == nil {
client = defaultClient
}
// initialize the default EncoderPool with Encoder headers
defaultHeaders := map[string]string{
"Datadog-Meta-Lang": "go",
Expand Down
Loading