Detection rules › Panther
AWS S3 Bucket Object Lock Configured
This policy validates that S3 buckets have an Object Lock configuration enabled. This should be used with specific suppression lists to ensure it is applied only to appropriate S3 buckets, such as those containing CloudTrail or other auditable records.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Impact | T1485 Data Destruction |
Rule body yaml
AnalysisType: policy
Filename: aws_s3_bucket_object_lock_configured.py
PolicyID: "AWS.S3.BucketObjectLockConfigured"
DisplayName: "AWS S3 Bucket Object Lock Configured"
Enabled: false
ResourceTypes:
- AWS.S3.Bucket
Tags:
- AWS
- S3
- PCI
- Impact:Data Destruction
Reports:
PCI:
- 10.5.3
MITRE ATT&CK:
- TA0040:T1485
Severity: Low
Description: >
This policy validates that S3 buckets have an Object Lock configuration enabled. This should be used with specific suppression lists to ensure it is applied only to appropriate S3 buckets, such as those containing CloudTrail or other auditable records.
Runbook: Create a new S3 bucket with an appropriate Object Lock configuration and point audit records to that bucket.
Reference: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html
Tests:
- Name: Object Lock Configured With Governance
ExpectedResult: false
Resource:
{
"AccountId": "123456789012",
"Arn": "arn:aws:s3:::example-bucket",
"EncryptionRules":
[
{
"ApplyServerSideEncryptionByDefault":
{ "KMSMasterKeyID": null, "SSEAlgorithm": "AES256" },
},
],
"Grants":
[
{
"Grantee":
{
"DisplayName": "example.user",
"EmailAddress": null,
"ID": "1",
"Type": "CanonicalUser",
"URI": null,
},
"Permission": "FULL_CONTROL",
},
],
"LifecycleRules": null,
"LoggingPolicy": null,
"MFADelete": "Disabled",
"Name": "example-bucket",
"ObjectLockConfiguration":
{
"ObjectLockEnabled": "Enabled",
"Rule":
{
"DefaultRetention":
{ "Days": 1, "Mode": "GOVERNANCE", "Years": null },
},
},
"Owner": { "DisplayName": "example.user", "ID": "1" },
"Policy": null,
"PublicAccessBlockConfiguration":
{
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
"RestrictPublicBuckets": true,
},
"Region": "us-west-2",
"ResourceId": "arn:aws:s3:::example-bucket",
"ResourceType": "AWS.S3.Bucket",
"Tags": { "environment": "pci" },
"TimeCreated": "2019-01-01T00:00:00.000Z",
"Versioning": "Enabled",
}
- Name: Object Lock Configured With Compliance
ExpectedResult: true
Resource:
{
"AccountId": "123456789012",
"Arn": "arn:aws:s3:::example-bucket",
"EncryptionRules":
[
{
"ApplyServerSideEncryptionByDefault":
{ "KMSMasterKeyID": null, "SSEAlgorithm": "AES256" },
},
],
"Grants":
[
{
"Grantee":
{
"DisplayName": "example.user",
"EmailAddress": null,
"ID": "1",
"Type": "CanonicalUser",
"URI": null,
},
"Permission": "FULL_CONTROL",
},
],
"LifecycleRules": null,
"LoggingPolicy": null,
"MFADelete": "Disabled",
"Name": "example-bucket",
"ObjectLockConfiguration":
{
"ObjectLockEnabled": "Enabled",
"Rule":
{
"DefaultRetention":
{ "Days": 365, "Mode": "COMPLIANCE", "Years": null },
},
},
"Owner": { "DisplayName": "example.user", "ID": "1" },
"Policy": null,
"PublicAccessBlockConfiguration":
{
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
"RestrictPublicBuckets": true,
},
"Region": "us-west-2",
"ResourceId": "arn:aws:s3:::example-bucket",
"ResourceType": "AWS.S3.Bucket",
"Tags": { "environment": "pci" },
"TimeCreated": "2019-01-01T00:00:00.000Z",
"Versioning": "Enabled",
}
- Name: Object Lock Not Configured
ExpectedResult: false
Resource:
{
"AccountId": "123456789012",
"Arn": "arn:aws:s3:::example-bucket",
"EncryptionRules":
[
{
"ApplyServerSideEncryptionByDefault":
{ "KMSMasterKeyID": null, "SSEAlgorithm": "AES256" },
},
],
"Grants":
[
{
"Grantee":
{
"DisplayName": "example.user",
"EmailAddress": null,
"ID": "1",
"Type": "CanonicalUser",
"URI": null,
},
"Permission": "FULL_CONTROL",
},
],
"LifecycleRules": null,
"LoggingPolicy": null,
"MFADelete": "Disabled",
"Name": "example-bucket",
"ObjectLockConfiguration":
{ "ObjectLockEnabled": "Disabled", "Rule": null },
"Owner": { "DisplayName": "example.user", "ID": "1" },
"Policy": null,
"PublicAccessBlockConfiguration":
{
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
"RestrictPublicBuckets": true,
},
"Region": "us-west-2",
"ResourceId": "arn:aws:s3:::example-bucket",
"ResourceType": "AWS.S3.Bucket",
"Tags": { "environment": "pci" },
"TimeCreated": "2019-01-01T00:00:00.000Z",
"Versioning": "Enabled",
}
Detection logic
Condition
not (not (ObjectLockConfiguration is_null or ObjectLockConfiguration.ObjectLockEnabled ne "Enabled" or ObjectLockConfiguration.Rule is_null) and ObjectLockConfiguration.Rule.DefaultRetention.Mode eq "COMPLIANCE" and ObjectLockConfiguration.Rule.DefaultRetention.Days ge "365")
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
ObjectLockConfiguration | is_null | |
ObjectLockConfiguration.ObjectLockEnabled | ne | Enabled |
ObjectLockConfiguration.Rule | is_null | |
ObjectLockConfiguration.Rule.DefaultRetention.Days | ge | 365 |
ObjectLockConfiguration.Rule.DefaultRetention.Mode | eq | COMPLIANCE |
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
ObjectLockConfiguration | is_null | |
ObjectLockConfiguration.ObjectLockEnabled | ne |
|
ObjectLockConfiguration.Rule | is_null |