Skip to content

Commit

Permalink
Merge branch 'main' into dario.castane/VULN-8316/insecure-default-wor…
Browse files Browse the repository at this point in the history
…kflow-permissions
  • Loading branch information
darccio authored Sep 26, 2024
2 parents ac793cf + bed7121 commit 7968a69
Show file tree
Hide file tree
Showing 156 changed files with 7,455 additions and 3,250 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/appsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
strategy:
matrix:
runs-on: [ macos-12, macos-14 ] # oldest and newest macos runners available - macos-14 mainly is here to cover the fact it is an ARM machine
go-version: [ "1.22", "1.21" ]
go-version: [ "1.23", "1.22" ]
fail-fast: true # saving some CI time - macos runners too long to get
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -190,7 +190,7 @@ jobs:
needs: go-mod-caching
strategy:
matrix:
go-version: [ "1.22", "1.21" ]
go-version: [ "1.23", "1.22" ]
distribution: [ bookworm, bullseye, alpine ]
platform: [ linux/amd64, linux/arm64 ]

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/main-branch-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
unit-integration-tests:
strategy:
matrix:
go-version: [ "1.21", "1.22" ]
go-version: [ "1.22", "1.23" ]
fail-fast: false
uses: ./.github/workflows/unit-integration-tests.yml
with:
Expand All @@ -33,7 +33,7 @@ jobs:
strategy:
matrix:
runs-on: [ macos-latest, windows-latest, ubuntu-latest ]
go-version: [ "1.21", "1.22" ]
go-version: [ "1.22", "1.23" ]
fail-fast: false
uses: ./.github/workflows/multios-unit-tests.yml
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ jobs:
name: PR Unit and Integration Tests
uses: ./.github/workflows/unit-integration-tests.yml
with:
go-version: "1.21"
go-version: "1.22"
ref: ${{ github.ref }}
secrets: inherit
6 changes: 3 additions & 3 deletions .github/workflows/smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
ref: ${{ inputs.ref || github.ref }}
- uses: actions/setup-go@v3
with:
go-version: "1.21"
go-version: "1.22"
cache: true
- name: go mod tidy
run: |-
Expand All @@ -109,7 +109,7 @@ jobs:
matrix:
# TODO: cross-compilation from/to different hardware architectures once
# github provides native ARM runners.
go: [ "1.21", "1.22", "1.23-rc" ]
go: [ "1.22", "1.23" ]
build-env: [ alpine, bookworm, bullseye ]
build-with-cgo: [ 0, 1 ]
deployment-env: [ alpine, debian11, debian12, al2, al2023, busybox, scratch ]
Expand Down Expand Up @@ -181,7 +181,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
file: ./internal/apps/setup-smoke-test/Dockerfile
file: ./internal/setup-smoke-test/Dockerfile
push: false
load: true
tags: smoke-test
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/system-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ jobs:
- uds-echo
scenario:
- DEFAULT
- INTEGRATIONS
- CROSSED_TRACING_LIBRARIES
- APPSEC_DISABLED
- APPSEC_BLOCKING
- APPSEC_BLOCKING_FULL_DENYLIST
Expand Down Expand Up @@ -106,6 +108,10 @@ jobs:
DD_API_KEY: ${{ secrets.DD_API_KEY }}
SYSTEM_TESTS_E2E_DD_API_KEY: ${{ secrets.SYSTEM_TESTS_E2E_DD_API_KEY }}
SYSTEM_TESTS_E2E_DD_APP_KEY: ${{ secrets.SYSTEM_TESTS_E2E_DD_APP_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.SYSTEM_TESTS_IDM_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SYSTEM_TESTS_IDM_AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
AWS_DEFAULT_REGION: us-east-1 # AWS services should use `AWS_REGION`, but some still use the older `AWS_DEFAULT_REGION`
name: Test (${{ matrix.weblog-variant }}, ${{ matrix.scenario }})
steps:
- name: Checkout system tests
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/unit-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ jobs:
uses: actions/checkout@v3
with:
ref: ${{ inputs.ref || github.ref }}

- name: Setup go
uses: actions/setup-go@v5
with:
go-version: stable
- name: Copyright
run: |
go run checkcopyright.go
Expand Down
4 changes: 2 additions & 2 deletions appsec/appsec.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"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/emitter/httpsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/sharedsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/usersec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
)

Expand Down Expand Up @@ -60,7 +60,7 @@ func SetUser(ctx context.Context, id string, opts ...tracer.UserMonitoringOption
appsecDisabledLog.Do(func() { log.Warn("appsec: not enabled. User blocking checks won't be performed.") })
return nil
}
return sharedsec.MonitorUser(ctx, id)
return usersec.MonitorUser(ctx, id)
}

// TrackUserLoginSuccessEvent sets a successful user login event, with the given
Expand Down
54 changes: 13 additions & 41 deletions contrib/99designs/gqlgen/appsec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,29 +58,20 @@ func TestAppSec(t *testing.T) {
testCases := map[string]struct {
query string
variables map[string]any
events map[string]string
}{
"basic": {
query: `query TestQuery($topLevelId: String!, $nestedId: String!) { topLevel(id: $topLevelId) { nested(id: $nestedId) } }`,
variables: map[string]any{
"topLevelId": topLevelAttack,
"nestedId": nestedAttack,
},
events: map[string]string{
"test-rule-001": "graphql.resolve(topLevel)",
"test-rule-002": "graphql.resolve(nested)",
},
},
"with-default-parameter": {
query: fmt.Sprintf(`query TestQuery($topLevelId: String = %#v, $nestedId: String!) { topLevel(id: $topLevelId) { nested(id: $nestedId) } }`, topLevelAttack),
variables: map[string]any{
// "topLevelId" omitted (default value used)
"nestedId": nestedAttack,
},
events: map[string]string{
"test-rule-001": "graphql.resolve(topLevel)",
"test-rule-002": "graphql.resolve(nested)",
},
},
"embedded-variable": {
query: `query TestQuery($topLevelId: String!, $nestedId: String!) {
Expand All @@ -92,10 +83,6 @@ func TestAppSec(t *testing.T) {
"topLevelId": topLevelAttack,
"nestedId": nestedAttack,
},
events: map[string]string{
"test-rule-001": "graphql.resolve(topLevelMapped)",
"test-rule-002": "graphql.resolve(nested)",
},
},
}
for name, tc := range testCases {
Expand All @@ -118,9 +105,9 @@ func TestAppSec(t *testing.T) {
require.NotEmpty(t, spans)

// The last finished span (which is GraphQL entry) should have the "_dd.appsec.enabled" tag.
require.Equal(t, 1, spans[len(spans)-1].Tag("_dd.appsec.enabled"))
span := spans[len(spans)-1]
require.Equal(t, 1, span.Tag("_dd.appsec.enabled"))

events := make(map[string]string)
type ddAppsecJSON struct {
Triggers []struct {
Rule struct {
Expand All @@ -129,34 +116,19 @@ func TestAppSec(t *testing.T) {
} `json:"triggers"`
}

// Search for AppSec events in the set of spans
for _, span := range spans {
jsonText, ok := span.Tag("_dd.appsec.json").(string)
if !ok || jsonText == "" {
continue
}
var parsed ddAppsecJSON
err := json.Unmarshal([]byte(jsonText), &parsed)
require.NoError(t, err)
jsonText, ok := span.Tag("_dd.appsec.json").(string)
require.True(t, ok, "expected _dd.appsec.json tag on span")

require.Len(t, parsed.Triggers, 1, "expected exactly 1 trigger on %s span", span.OperationName())
ruleID := parsed.Triggers[0].Rule.ID
_, duplicate := events[ruleID]
require.False(t, duplicate, "found duplicated hit for rule %s", ruleID)
var origin string
switch name := span.OperationName(); name {
case "graphql.field":
field := span.Tag(tagGraphqlField).(string)
origin = fmt.Sprintf("%s(%s)", "graphql.resolve", field)
case "graphql.query":
origin = "graphql.execute"
default:
require.Fail(t, "rule trigger recorded on unecpected span", "rule %s recorded a hit on unexpected span %s", ruleID, name)
}
events[ruleID] = origin
var parsed ddAppsecJSON
err = json.Unmarshal([]byte(jsonText), &parsed)
require.NoError(t, err)

ids := make([]string, 0, len(parsed.Triggers))
for _, trigger := range parsed.Triggers {
ids = append(ids, trigger.Rule.ID)
}
// Ensure they match the expected outcome
require.Equal(t, tc.events, events)

require.ElementsMatch(t, ids, []string{"test-rule-001", "test-rule-002"})
})
}
})
Expand Down
13 changes: 6 additions & 7 deletions contrib/99designs/gqlgen/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ import (
"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/emitter/graphqlsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/graphqlsec/types"
"gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema"
"gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry"

Expand Down Expand Up @@ -104,12 +103,12 @@ func (t *gqlTracer) Validate(_ graphql.ExecutableSchema) error {
func (t *gqlTracer) InterceptOperation(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler {
opCtx := graphql.GetOperationContext(ctx)
span, ctx := t.createRootSpan(ctx, opCtx)
ctx, req := graphqlsec.StartRequestOperation(ctx, span, types.RequestOperationArgs{
ctx, req := graphqlsec.StartRequestOperation(ctx, graphqlsec.RequestOperationArgs{
RawQuery: opCtx.RawQuery,
OperationName: opCtx.OperationName,
Variables: opCtx.Variables,
})
ctx, query := graphqlsec.StartExecutionOperation(ctx, span, types.ExecutionOperationArgs{
ctx, query := graphqlsec.StartExecutionOperation(ctx, graphqlsec.ExecutionOperationArgs{
Query: opCtx.RawQuery,
OperationName: opCtx.OperationName,
Variables: opCtx.Variables,
Expand All @@ -124,11 +123,11 @@ func (t *gqlTracer) InterceptOperation(ctx context.Context, next graphql.Operati
}
defer span.Finish(tracer.WithError(err))
}
query.Finish(types.ExecutionOperationRes{
query.Finish(graphqlsec.ExecutionOperationRes{
Data: response.Data, // NB - This is raw data, but rather not parse it (possibly expensive).
Error: response.Errors,
})
req.Finish(types.RequestOperationRes{
req.Finish(span, graphqlsec.RequestOperationRes{
Data: response.Data, // NB - This is raw data, but rather not parse it (possibly expensive).
Error: response.Errors,
})
Expand Down Expand Up @@ -167,13 +166,13 @@ func (t *gqlTracer) InterceptField(ctx context.Context, next graphql.Resolver) (

span, ctx := tracer.StartSpanFromContext(ctx, fieldOp, opts...)
defer func() { span.Finish(tracer.WithError(err)) }()
ctx, op := graphqlsec.StartResolveOperation(ctx, span, types.ResolveOperationArgs{
ctx, op := graphqlsec.StartResolveOperation(ctx, graphqlsec.ResolveOperationArgs{
Arguments: fieldCtx.Args,
TypeName: fieldCtx.Object,
FieldName: fieldCtx.Field.Name,
Trivial: isTrivial,
})
defer func() { op.Finish(types.ResolveOperationRes{Data: res, Error: err}) }()
defer func() { op.Finish(graphqlsec.ResolveOperationRes{Data: res, Error: err}) }()

res, err = next(ctx)
return
Expand Down
31 changes: 23 additions & 8 deletions contrib/aws/aws-sdk-go-v2/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,21 +229,23 @@ func tableName(requestInput middleware.InitializeInput) string {
func streamName(requestInput middleware.InitializeInput) string {
switch params := requestInput.Parameters.(type) {
case *kinesis.PutRecordInput:
return *params.StreamName
return coalesceNameOrArnResource(params.StreamName, params.StreamARN)
case *kinesis.PutRecordsInput:
return *params.StreamName
return coalesceNameOrArnResource(params.StreamName, params.StreamARN)
case *kinesis.AddTagsToStreamInput:
return *params.StreamName
return coalesceNameOrArnResource(params.StreamName, params.StreamARN)
case *kinesis.RemoveTagsFromStreamInput:
return *params.StreamName
return coalesceNameOrArnResource(params.StreamName, params.StreamARN)
case *kinesis.CreateStreamInput:
return *params.StreamName
if params.StreamName != nil {
return *params.StreamName
}
case *kinesis.DeleteStreamInput:
return *params.StreamName
return coalesceNameOrArnResource(params.StreamName, params.StreamARN)
case *kinesis.DescribeStreamInput:
return *params.StreamName
return coalesceNameOrArnResource(params.StreamName, params.StreamARN)
case *kinesis.DescribeStreamSummaryInput:
return *params.StreamName
return coalesceNameOrArnResource(params.StreamName, params.StreamARN)
case *kinesis.GetRecordsInput:
if params.StreamARN != nil {
streamArnValue := *params.StreamARN
Expand Down Expand Up @@ -353,3 +355,16 @@ func serviceName(cfg *config, awsService string) string {
defaultName := fmt.Sprintf("aws.%s", awsService)
return namingschema.ServiceNameOverrideV0(defaultName, defaultName)
}

func coalesceNameOrArnResource(name *string, arnVal *string) string {
if name != nil {
return *name
}

if arnVal != nil {
parts := strings.Split(*arnVal, "/")
return parts[len(parts)-1]
}

return ""
}
62 changes: 62 additions & 0 deletions contrib/aws/aws-sdk-go-v2/aws/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/sns"
"github.com/aws/aws-sdk-go-v2/service/sqs"
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
"github.com/aws/smithy-go/middleware"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -1077,3 +1078,64 @@ func TestWithErrorCheck(t *testing.T) {
})
}
}

func TestStreamName(t *testing.T) {
dummyName := `my-stream`
dummyArn := `arn:aws:kinesis:us-east-1:111111111111:stream/` + dummyName

tests := []struct {
name string
input any
expected string
}{
{
name: "PutRecords with ARN",
input: &kinesis.PutRecordsInput{StreamARN: &dummyArn},
expected: dummyName,
},
{
name: "PutRecords with Name",
input: &kinesis.PutRecordsInput{StreamName: &dummyName},
expected: dummyName,
},
{
name: "PutRecords with both",
input: &kinesis.PutRecordsInput{StreamName: &dummyName, StreamARN: &dummyArn},
expected: dummyName,
},
{
name: "PutRecord with Name",
input: &kinesis.PutRecordInput{StreamName: &dummyName},
expected: dummyName,
},
{
name: "CreateStream",
input: &kinesis.CreateStreamInput{StreamName: &dummyName},
expected: dummyName,
},
{
name: "CreateStream with nothing",
input: &kinesis.CreateStreamInput{},
expected: "",
},
{
name: "GetRecords",
input: &kinesis.GetRecordsInput{StreamARN: &dummyArn},
expected: dummyName,
},
{
name: "GetRecords with nothing",
input: &kinesis.GetRecordsInput{},
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := middleware.InitializeInput{
Parameters: tt.input,
}
val := streamName(req)
assert.Equal(t, tt.expected, val)
})
}
}
Loading

0 comments on commit 7968a69

Please sign in to comment.