Back to Checks
S3 bucket has object versioning enabled
s3_bucket_object_versioning
Service: s3Severity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:AwsS3Bucket
Amazon S3 buckets are evaluated for object versioning being Enabled, which maintains multiple versions of the same object key for historical state retention
Risk
Without versioning, deletions and overwrites remove the only copy, undermining availability and integrity.
- Compromised identities or buggy apps can mass-delete/corrupt data
- No historical versions means limited rollback and irrecoverable loss
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks s3_bucket_object_versioningRecommendation
Enable S3 versioning for buckets holding important or shared data.
- Enforce least privilege to limit delete/overwrite
- Use Object Lock and/or MFA Delete for stronger protection
- Apply lifecycle rules to manage noncurrent versions and costs
- Layer with backups/replication for defense in depth
Remediation
CLI
aws s3api put-bucket-versioning --bucket <BUCKET_NAME> --versioning-configuration Status=EnabledTerraform
# Enable versioning on an existing S3 bucket
resource "aws_s3_bucket_versioning" "<example_resource_name>" {
bucket = "<example_resource_name>"
versioning_configuration {
status = "Enabled" # Critical: enables bucket versioning to remediate the finding
}
}NativeIaC
# CloudFormation: enable versioning on an S3 bucket
Resources:
<example_resource_name>:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled # Critical: turns on object versioning to pass the checkOther
1In the AWS Console, go to S3 > Buckets and select the target bucket
2Open the Properties tab
3Find Bucket Versioning and click Edit
4Select Enable and click Save changes
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.s3.s3_client import s3_client
class s3_bucket_object_versioning(Check):
"""Ensure S3 buckets have object versioning enabled.
- PASS: Versioning is enabled.
- FAIL: Versioning is disabled.
- MANUAL: The versioning configuration could not be retrieved (missing
permissions), so the status cannot be asserted.
"""
def execute(self) -> list[Check_Report_AWS]:
"""Evaluate versioning for every audited bucket.
Returns:
list[Check_Report_AWS]: One report per bucket.
"""
findings = []
for bucket in s3_client.buckets.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=bucket)
if not bucket.versioning_retrieved:
report.status = "MANUAL"
report.status_extended = f"Cannot evaluate versioning for S3 Bucket {bucket.name}: the versioning configuration could not be retrieved. Verify that the scanning credentials are allowed to call s3:GetBucketVersioning."
elif bucket.versioning:
report.status = "PASS"
report.status_extended = (
f"S3 Bucket {bucket.name} has versioning enabled."
)
else:
report.status = "FAIL"
report.status_extended = (
f"S3 Bucket {bucket.name} has versioning disabled."
)
findings.append(report)
return findings