Back to Checks
aws

S3 bucket has MFA Delete enabled

s3_bucket_no_mfa_delete
Service: s3Severity: medium
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:AwsS3Bucket

Amazon S3 buckets are assessed for MFA Delete status. MFA Delete requires a second factor to permanently delete object versions or change Versioning configuration. The finding highlights buckets where this protection is not enabled.

Risk

Without MFA Delete, a compromised or over-privileged identity can irrevocably purge object history or change versioning.

This erases recovery points, degrading data availability, weakening integrity, and increasing the blast radius of account compromise or ransomware.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks s3_bucket_no_mfa_delete

Recommendation

Enable MFA Delete on sensitive, versioned buckets so permanent deletions and Versioning changes require a second factor. Apply least privilege to restrict version purge actions, enforce change control, and combine with Object Lock or immutable backups for defense in depth.

Remediation

CLI

aws s3api put-bucket-versioning --bucket <BUCKET_NAME> --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa "<MFA_SERIAL_OR_ARN> <MFA_CODE>"

Other

1Sign in to the AWS Management Console as the root user
2Open the account menu > Security credentials > Multi-factor authentication (MFA) and assign an MFA device; copy its ARN/serial
3From a machine configured to use the root user credentials, run:
4```bash
5aws s3api put-bucket-versioning --bucket <BUCKET_NAME> --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa "<MFA_SERIAL_OR_ARN> <MFA_CODE>"
6```

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_no_mfa_delete(Check):
    def execute(self):
        findings = []
        for bucket in s3_client.buckets.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=bucket)
            if bucket.mfa_delete:
                report.status = "PASS"
                report.status_extended = (
                    f"S3 Bucket {bucket.name} has MFA Delete enabled."
                )
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"S3 Bucket {bucket.name} has MFA Delete disabled."
                )
            findings.append(report)

        return findings