Skip to content

Commit

Permalink
Update S3 ARN Handling for AccessPoints and Outpost ARNs (#3928)
Browse files Browse the repository at this point in the history
  • Loading branch information
skmcgrail committed Jun 4, 2021
1 parent 0b5551c commit 3f59f86
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 68 deletions.
4 changes: 4 additions & 0 deletions internal/s3shared/arn/arn.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ func ParseResource(s string, resParser ResourceParser) (resARN Resource, err err
return nil, InvalidARNError{ARN: a, Reason: "service is not supported"}
}

if strings.HasPrefix(a.Region, "fips-") || strings.HasSuffix(a.Region, "-fips") {
return nil, InvalidARNError{ARN: a, Reason: "FIPS region not allowed in ARN"}
}

if len(a.Resource) == 0 {
return nil, InvalidARNError{ARN: a, Reason: "resource not set"}
}
Expand Down
8 changes: 8 additions & 0 deletions internal/s3shared/arn/arn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ func TestParseResource(t *testing.T) {
AccessPointName: "myendpoint",
},
},
"invalid FIPS pseudo region in ARN (prefix)": {
Input: "arn:aws:s3:fips-us-west-2:012345678901:accesspoint/myendpoint",
ExpectErr: "FIPS region not allowed in ARN",
},
"invalid FIPS pseudo region in ARN (suffix)": {
Input: "arn:aws:s3:us-west-2-fips:012345678901:accesspoint/myendpoint",
ExpectErr: "FIPS region not allowed in ARN",
},
}

for name, c := range cases {
Expand Down
13 changes: 13 additions & 0 deletions internal/s3shared/endpoint_errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ func NewInvalidARNWithUnsupportedPartitionError(resource arn.Resource, err error
}

// NewInvalidARNWithFIPSError ARN not supported for FIPS region
//
// Deprecated: FIPS will not appear in the ARN region component.
func NewInvalidARNWithFIPSError(resource arn.Resource, err error) InvalidARNError {
return InvalidARNError{
message: "resource ARN not supported for FIPS region",
Expand Down Expand Up @@ -155,6 +157,17 @@ func NewClientConfiguredForFIPSError(resource arn.Resource, clientPartitionID, c
}
}

// NewFIPSConfigurationError denotes a configuration error when a client or request is configured for FIPS
func NewFIPSConfigurationError(resource arn.Resource, clientPartitionID, clientRegion string, err error) ConfigurationError {
return ConfigurationError{
message: "use of ARN is not supported when client or request is configured for FIPS",
origErr: err,
resource: resource,
clientPartitionID: clientPartitionID,
clientRegion: clientRegion,
}
}

// NewClientConfiguredForAccelerateError denotes client config error for unsupported S3 accelerate
func NewClientConfiguredForAccelerateError(resource arn.Resource, clientPartitionID, clientRegion string, err error) ConfigurationError {
return ConfigurationError{
Expand Down
2 changes: 2 additions & 0 deletions internal/s3shared/resource_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ func (r ResourceRequest) UseFIPS() bool {
}

// ResourceConfiguredForFIPS returns true if resource ARNs region is FIPS
//
// Deprecated: FIPS pseudo-regions will not be in the ARN
func (r ResourceRequest) ResourceConfiguredForFIPS() bool {
return IsFIPS(r.ARN().Region)
}
Expand Down
5 changes: 3 additions & 2 deletions service/s3/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ func endpointHandler(req *request.Request) {
}
case arn.OutpostAccessPointARN:
// outposts does not support FIPS regions
if resReq.ResourceConfiguredForFIPS() {
req.Error = s3shared.NewInvalidARNWithFIPSError(resource, nil)
if resReq.UseFIPS() {
req.Error = s3shared.NewFIPSConfigurationError(resource, req.ClientInfo.PartitionID,
aws.StringValue(req.Config.Region), nil)
return
}

Expand Down
73 changes: 58 additions & 15 deletions service/s3/endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,36 +265,31 @@ func TestEndpoint(t *testing.T) {
expectedSigningName: "s3-outposts",
expectedSigningRegion: "us-gov-east-1",
},
"Outpost AccessPoint Fips region": {
"Outpost AccessPoint FIPS client region": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("fips-us-gov-east-1"),
},
expectedErr: "ConfigurationError: client region does not match provided ARN region",
},
"Outpost AccessPoint Fips region in Arn": {
bucket: "arn:aws-us-gov:s3-outposts:fips-us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
"Outpost AccessPoint FIPS client region with matching ARN region": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
EnforceShouldRetryCheck: nil,
Region: aws.String("fips-us-gov-east-1"),
DisableSSL: nil,
HTTPClient: nil,
S3UseARNRegion: aws.Bool(true),
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("fips-us-gov-east-1"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "InvalidARNError: resource ARN not supported for FIPS region",
expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
},
"Outpost AccessPoint Fips region with valid ARN region": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
"Outpost AccessPoint FIPS client region with cross-region ARN": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-west-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("fips-us-gov-east-1"),
S3UseARNRegion: aws.Bool(true),
},
expectedEndpoint: "https://myaccesspoint-123456789012.op-01234567890123456.s3-outposts.us-gov-east-1.amazonaws.com",
expectedSigningName: "s3-outposts",
expectedSigningRegion: "us-gov-east-1",
expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
},
"Outpost AccessPoint with DualStack": {
bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
Expand Down Expand Up @@ -571,6 +566,54 @@ func TestEndpoint(t *testing.T) {
expectedSigningName: "s3",
expectedSigningRegion: "us-west-2",
},
"Invalid AccessPoint ARN with FIPS pseudo-region (prefix)": {
bucket: "arn:aws:s3:fips-us-east-1:123456789012:accesspoint:myendpoint",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
"Invalid AccessPoint ARN with FIPS pseudo-region (suffix)": {
bucket: "arn:aws:s3:us-east-1-fips:123456789012:accesspoint:myendpoint",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
"Invalid Outpost AccessPoint ARN with FIPS pseudo-region (prefix)": {
bucket: "arn:aws:s3-outposts:fips-us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
"Invalid Outpost AccessPoint ARN with FIPS pseudo-region (suffix)": {
bucket: "arn:aws:s3-outposts:us-east-1-fips:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
"Invalid Object Lambda ARN with FIPS pseudo-region (prefix)": {
bucket: "arn:aws:s3-object-lambda:fips-us-east-1:123456789012:accesspoint/myap",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
"Invalid Object Lambda ARN with FIPS pseudo-region (suffix)": {
bucket: "arn:aws:s3-object-lambda:us-east-1-fips:123456789012:accesspoint/myap",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
}

for name, c := range cases {
Expand Down
5 changes: 3 additions & 2 deletions service/s3control/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,9 @@ func validateOutpostEndpoint(req *request.Request, resource arn.Resource) error
}

// resource configured with FIPS as region is not supported by outposts
if resReq.ResourceConfiguredForFIPS() {
return s3shared.NewInvalidARNWithFIPSError(resource, nil)
if resReq.UseFIPS() {
return s3shared.NewFIPSConfigurationError(resource, req.ClientInfo.PartitionID,
aws.StringValue(req.Config.Region), nil)
}

// DualStack not supported
Expand Down
5 changes: 0 additions & 5 deletions service/s3control/endpoint_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ type outpostAccessPointEndpointBuilder arn.OutpostAccessPointARN
func (o outpostAccessPointEndpointBuilder) build(req *request.Request) error {
resolveRegion := o.Region
resolveService := o.Service
cfgRegion := aws.StringValue(req.Config.Region)

if s3shared.IsFIPS(cfgRegion) && !aws.BoolValue(req.Config.S3UseARNRegion) {
return s3shared.NewInvalidARNWithFIPSError(o, nil)
}

endpointsID := resolveService
if resolveService == "s3-outposts" {
Expand Down
93 changes: 49 additions & 44 deletions service/s3control/endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,51 +80,31 @@ func TestEndpoint_OutpostAccessPointARN(t *testing.T) {
expectedHeaderForAccountID: true,
expectedHeaderForOutpostID: "op-01234567890123456",
},
"Outpost AccessPoint with client region as Fips": {
"Outpost AccessPoint with client region as FIPS": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("us-gov-east-1-fips"),
},
expectedErr: "InvalidARNError: resource ARN not supported for FIPS region",
expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
},
"Outpost AccessPoint with client Fips region and use arn region enabled": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
"Outpost AccessPoint with client FIPS region and cross-region ARN": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-west-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("us-gov-east-1-fips"),
S3UseARNRegion: aws.Bool(true),
},
expectedSigningName: "s3-outposts",
expectedSigningRegion: "us-gov-east-1",
expectedEndpoint: "https://s3-outposts.us-gov-east-1.amazonaws.com",
expectedHeaderForAccountID: true,
expectedHeaderForOutpostID: "op-01234567890123456",
expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
},
"Outpost AccessPoint Fips region in Arn": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1-fips:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
EnforceShouldRetryCheck: nil,
Region: aws.String("us-gov-east-1-fips"),
DisableSSL: nil,
HTTPClient: nil,
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "InvalidARNError: resource ARN not supported for FIPS region",
},
"Outpost AccessPoint Fips region with valid ARN region": {
"Outpost AccessPoint FIPS client region with matching ARN region": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("fips-us-gov-east-1"),
S3UseARNRegion: aws.Bool(true),
},
expectedEndpoint: "https://s3-outposts.us-gov-east-1.amazonaws.com",
expectedSigningName: "s3-outposts",
expectedSigningRegion: "us-gov-east-1",
expectedHeaderForAccountID: true,
expectedHeaderForOutpostID: "op-01234567890123456",
expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
},
"Outpost AccessPoint with DualStack": {
bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
Expand Down Expand Up @@ -180,6 +160,22 @@ func TestEndpoint_OutpostAccessPointARN(t *testing.T) {
},
expectedErr: "invalid Amazon s3-outposts ARN",
},
"Invalid Outpost AccessPoint ARN with FIPS pseudo-region (prefix)": {
bucket: "arn:aws-us-gov:s3-outposts:fips-us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
"Invalid Outpost AccessPoint ARN with FIPS pseudo-region (suffix)": {
bucket: "arn:aws-us-gov:s3-outposts:us-east-1-fips:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
}

runValidations(t, cases)
Expand Down Expand Up @@ -238,38 +234,31 @@ func TestEndpoint_OutpostBucketARN(t *testing.T) {
expectedHeaderForOutpostID: "op-01234567890123456",
expectedHeaderForAccountID: true,
},
"Outpost Bucket Fips region": {
"Outpost Bucket FIPS client region": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("fips-us-gov-east-1"),
},
expectedErr: "ConfigurationError: client region does not match provided ARN region",
},
"Outpost Bucket Fips region in Arn": {
bucket: "arn:aws-us-gov:s3-outposts:fips-us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
"Outpost Bucket FIPS client region with match ARN region": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
EnforceShouldRetryCheck: nil,
Region: aws.String("fips-us-gov-east-1"),
DisableSSL: nil,
HTTPClient: nil,
S3UseARNRegion: aws.Bool(true),
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("fips-us-gov-east-1"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "InvalidARNError: resource ARN not supported for FIPS region",
expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
},
"Outpost Bucket Fips region with valid ARN region": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
"Outpost Bucket FIPS client region with cross-region ARN": {
bucket: "arn:aws-us-gov:s3-outposts:us-gov-west-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
config: &aws.Config{
EndpointResolver: endpoints.AwsUsGovPartition(),
Region: aws.String("fips-us-gov-east-1"),
S3UseARNRegion: aws.Bool(true),
},
expectedEndpoint: "https://s3-outposts.us-gov-east-1.amazonaws.com",
expectedSigningName: "s3-outposts",
expectedSigningRegion: "us-gov-east-1",
expectedHeaderForOutpostID: "op-01234567890123456",
expectedHeaderForAccountID: true,
expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
},
"Outpost Bucket with DualStack": {
bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket",
Expand Down Expand Up @@ -302,6 +291,22 @@ func TestEndpoint_OutpostBucketARN(t *testing.T) {
},
expectedErr: "invalid Amazon s3-outposts ARN, unknown resource type",
},
"Invalid Outpost Bucket ARN with FIPS pseudo-region (prefix)": {
bucket: "arn:aws:s3-outposts:fips-us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
"Invalid Outpost Bucket ARN with FIPS pseudo-region (suffix)": {
bucket: "arn:aws:s3-outposts:us-east-1-fips:123456789012:outpost:op-01234567890123456:bucket:mybucket",
config: &aws.Config{
Region: aws.String("us-west-2"),
S3UseARNRegion: aws.Bool(true),
},
expectedErr: "FIPS region not allowed in ARN",
},
}

runValidations(t, cases)
Expand Down

0 comments on commit 3f59f86

Please sign in to comment.