> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# S3 Bucket Changes Alarm

### More Info:

AWS S3 Buckets configuration changes should be monitored using CloudWatch alarms. An alarm should be configured to trigger every time an S3 bucket configuration change is made, such as changes to bucket policies, ACLs, or lifecycle configurations.

### Risk Level

Medium

### Address

Security

### Compliance Standards

CISAWS, CBP, SOC2, NIST, AWSWAF, HITRUST, NISTCSF, PCIDSS, CISAWSF, PCI, APRA, MAS, NIST4

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        When you receive an S3 Bucket Changes Alarm, it indicates that there has been a change in the configuration of one of your S3 buckets. Here are the steps to remediate this issue in the AWS Console:

        1. Log in to your AWS Management Console and navigate to the CloudWatch dashboard at [CloudWatch Console](https://console.aws.amazon.com/cloudwatch/).

        2. In the left navigation panel, select **Logs**.

        3. Select the log group created for your CloudTrail trail event logs and click on **Create Metric Filter**.

        4. On the **Define Logs Metric Filter** page, paste the following pattern inside the **Filter Pattern** box:

        ```
        {
            ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) ||
            ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) ||
            ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) ||
            ($.eventName = DeleteBucketReplication))
        }
        ```

        This pattern will be used for scanning the AWS CloudTrail logs for relevant event names.

        5. Review the metric filter configuration details and then click **Assign Metric**.

        6. On the **Create Metric Filter and Assign a Metric** page, provide the following:

           * In the **Filter Name** box, enter a unique name (e.g., `S3BucketConfigChanges`).
           * In the **Metric Namespace** box, type `CloudTrailMetrics`.
           * In the **Metric Name** box, type `S3BucketEventCount`.
           * Click **Show advanced metric settings** to expand the section.
           * In the **Metric Value** box, enter `1`.

        7. Review the details and click **Create Filter** to generate your new CloudWatch Logs metric filter.

        8. Click **Create Alarm** on the same page:

        9. In the **Create Alarm** dialog box, enter a unique name and description for the alarm.

        10. Under **Whenever: Metric Name**, select `>=` (greater than or equal to) and enter `1` as the threshold value.

        11. In the **Actions** section, click the **+ Notification** button, select `State is ALARM`, and choose the AWS SNS topic created earlier.

        12. In the **Alarm Preview** section, select `5 Minutes` from the **Period** dropdown and `Sum` from the **Statistic** list.

        13. Review the configuration details and click **Create Alarm**. The new alarm will be listed on the Alarms page.

        #
      </Accordion>

      <Accordion title="Using CLI">
        To remediate the S3 Bucket Changes Alarm using the AWS CLI, follow these steps:

        1. Run the following command to create the necessary CloudWatch metric filter and associate it with the appropriate Amazon CloudTrail log group:

        ```bash theme={null}
        aws logs put-metric-filter
            --region us-east-1
            --log-group-name CloudTrail/CloudWatchLogGroup
            --filter-name S3BucketConfigChanges
            --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }'
            --metric-transformations metricName=S3BucketEventCount,metricNamespace=CloudTrailMetrics,metricValue=1
        ```

        2. Run the following command to create the AWS CloudWatch alarm that will fire whenever a configuration change involving an S3 Bucket is made:

        ```bash theme={null}
        aws cloudwatch put-metric-alarm
            --region us-east-1
            --alarm-name S3BucketConfigChangesAlarm
            --alarm-description "Triggered by AWS S3 Bucket config changes."
            --metric-name S3BucketEventCount
            --namespace CloudTrailMetrics
            --statistic Sum
            --comparison-operator GreaterThanOrEqualToThreshold
            --evaluation-periods 1
            --period 300
            --threshold 1
            --actions-enabled
            --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmSNSTopic
        ```

        #
      </Accordion>

      <Accordion title="Using Python">
        You can also use Python to remediate the S3 Bucket Changes Alarm. Below is a script that utilizes the Boto3 library:

        ```
        import boto3
        import json

        # Define the S3 bucket name
        bucket_name = 'my-bucket'

        # Create a client object for S3
        s3 = boto3.client('s3')

        # Update the bucket policy to restrict public access
        bucket_policy = {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Deny",
                    "Principal": "*",
                    "Action": "s3:*",
                    "Resource": [
                        f"arn:aws:s3:::{bucket_name}/*",
                        f"arn:aws:s3:::{bucket_name}"
                    ],
                    "Condition": {
                        "Bool": {
                            "aws:SecureTransport": "false"
                        }
                    }
                }
            ]
        }
        s3.put_bucket_policy(Bucket=bucket_name, Policy=json.dumps(bucket_policy))

        # Update the bucket ACL to restrict public access
        bucket_acl = s3.get_bucket_acl(Bucket=bucket_name)
        for grant in bucket_acl['Grants']:
            if grant['Grantee'].get('URI') == 'http://acs.amazonaws.com/groups/global/AllUsers':
                s3.put_bucket_acl(Bucket=bucket_name, ACL='private')
                break
        ```

        Note: Replace `my-bucket` with the actual name of the S3 bucket.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://docs.aws.amazon.com/AmazonS3/latest/userguide/cloudwatch-monitoring.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cloudwatch-monitoring.html)
* [https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/CloudWatchLogs/s3-bucket-changes-alarm.html](https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/CloudWatchLogs/s3-bucket-changes-alarm.html)
