ScoutSuite icon indicating copy to clipboard operation
ScoutSuite copied to clipboard

False positive: Bucket Allowing Clear Text (HTTP) Communication (AWS policy key names not case-sensitive)

Open cckev opened this issue 1 year ago • 1 comments

Describe the bug

Using bucket policies, users can deny all S3 actions on a bucket and its contents if the request is not over SSL/TLS (ref: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Boolean). Under certain conditions, ScoutSuite alerts a false positive when AWS users enforce TLS for s3 transport via bucket policy.

The related ScoutSuite finding checks for the condition key name aws:SecureTransport (ref: https://github.com/nccgroup/ScoutSuite/blob/develop/ScoutSuite/providers/aws/facade/s3.py#L270) but does not account for variations of letter cases for the key name.

According to AWS documentation:

Condition key names are not case-sensitive. For example, including the aws:SourceIP condition key is equivalent to testing for AWS:SourceIp.

This means, users can specify the aws:SecureTransport condition key name using any letter casing (ie. aws:securetransport) and still provide a valid bucket policy. The ScoutSuite check likely needs to account for all letter case variations of the key name.

To Reproduce

The following reproduction tests show an s3 bucket policy that uses aws:securetransport for the condition key name and shows that the bucket policy is interpreted differently using all lower casing for aws:securetransport :

Policy 1 (deny http requests)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "BooleanExample",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::test-bucket-for-condition-key-case-sensitivity",
                "arn:aws:s3:::test-bucket-for-condition-key-case-sensitivity/*"
            ],
            "Condition": {
                "Bool": {
                    "aws:securetransport": "false"
                }
            }
        }
    ]
}

Response 1

$ curl -v http://test-bucket-for-condition-key-case-sensitivity.s3.amazonaws.com/test.txt
*   Trying 52.216.142.188:80...
* Connected to test-bucket-for-condition-key-case-sensitivity.s3.amazonaws.com (52.216.142.188) port 80 (#0)
> GET /test.txt HTTP/1.1
> Host: test-bucket-for-condition-key-case-sensitivity.s3.amazonaws.com
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
[snip...]
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>K0JC5NCHW9KCZ7A1</RequestId><HostId>FmpdaEqLHLEa6REt1q0t6vmnEsTYBvOhqZigtFIAYuCbq6VzQc3gK/CsdPuXz3o4WNGkgfemDqg=</HostId></Error>

Policy 2 (allow http requests)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "BooleanExample",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::test-bucket-for-condition-key-case-sensitivity",
                "arn:aws:s3:::test-bucket-for-condition-key-case-sensitivity/*"
            ],
            "Condition": {
                "Bool": {
                    "aws:securetransport": "false"
                }
            }
        }
    ]
}

Response 2

$ curl -v http://test-bucket-for-condition-key-case-sensitivity.s3.amazonaws.com/test.txt
*   Trying 52.216.24.4:80...
* Connected to test-bucket-for-condition-key-case-sensitivity.s3.amazonaws.com (52.216.24.4) port 80 (#0)
> GET /test.txt HTTP/1.1
> Host: test-bucket-for-condition-key-case-sensitivity.s3.amazonaws.com
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
[snip...]
< x-amz-server-side-encryption: AES256
< Accept-Ranges: bytes
< Content-Type: text/plain
< Server: AmazonS3
< Content-Length: 5
< 
test

cckev avatar Apr 16 '23 22:04 cckev

Interesting! We can certainly take a look

liyun-li avatar May 11 '23 21:05 liyun-li