Skip to content

Commit

Permalink
Add support for confused deputy headers
Browse files Browse the repository at this point in the history
  • Loading branch information
dricross committed Jan 15, 2025
1 parent d03e737 commit 1889c8a
Showing 1 changed file with 29 additions and 2 deletions.
31 changes: 29 additions & 2 deletions internal/aws/awsutil/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sts"
"go.uber.org/zap"
Expand Down Expand Up @@ -458,7 +459,7 @@ func getCredentialProviderChain(cfg *AWSSessionSettings) []credentials.Provider

func newStsCredentials(c client.ConfigProvider, roleARN string, region string) *credentials.Credentials {
regional := &stscreds.AssumeRoleProvider{
Client: sts.New(c, &aws.Config{
Client: newStsClient(c, &aws.Config{
Region: aws.String(region),
STSRegionalEndpoint: endpoints.RegionalSTSEndpoint,
HTTPClient: &http.Client{Timeout: 1 * time.Minute},
Expand All @@ -470,7 +471,7 @@ func newStsCredentials(c client.ConfigProvider, roleARN string, region string) *
fallbackRegion := getFallbackRegion(region)

partitional := &stscreds.AssumeRoleProvider{
Client: sts.New(c, &aws.Config{
Client: newStsClient(c, &aws.Config{
Region: aws.String(fallbackRegion),
Endpoint: aws.String(getFallbackEndpoint(fallbackRegion)),
STSRegionalEndpoint: endpoints.RegionalSTSEndpoint,
Expand All @@ -483,6 +484,32 @@ func newStsCredentials(c client.ConfigProvider, roleARN string, region string) *
return credentials.NewCredentials(&stsCredentialProvider{regional: regional, partitional: partitional})
}

var (
sourceAccount = os.Getenv("AMZ_SOURCE_ACCOUNT") // populates the "x-amz-source-account" header
sourceArn = os.Getenv("AMZ_SOURCE_ARN") // populates the "x-amz-source-arn" header
)

// newStsClient creates a new STS client with the provided config and options.
// Additionally, if specific environment variables are set, it also appends the confused deputy headers to requests
// made by the client. These headers allow resource-based policies to limit the permissions that a service has to
// a specific resource. Note that BOTH environment variables need to contain non-empty values in order for the headers
// to be set.
//
// See https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#cross-service-confused-deputy-prevention
func newStsClient(p client.ConfigProvider, cfgs ...*aws.Config) *sts.STS {
client := sts.New(p, cfgs...)
if sourceAccount != "" && sourceArn != "" {
client.Handlers.Sign.PushFront(func(r *request.Request) {
r.ApplyOptions(request.WithSetRequestHeaders(map[string]string{
"x-amz-source-arn": sourceArn,
"x-amz-source-account": sourceAccount,
}))
})
}

return client
}

func getFallbackRegion(region string) string {
partition := getEndpointPartition(region)
switch partition.ID() {
Expand Down

0 comments on commit 1889c8a

Please sign in to comment.