Cognito user pool password policy requires at least one lowercase letter
Amazon Cognito user pools are assessed for a password policy that includes a lowercase character requirement. Pools with require_lowercase set are distinguished from those without a policy, which inherently lack this requirement.
Risk
Absent a lowercase requirement reduces password complexity and the overall keyspace, making brute-force and credential stuffing more feasible. Successful guessing enables account takeover, exposing user data and tokens and permitting profile changes, harming confidentiality and integrity.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks cognito_user_pool_password_policy_lowercaseRecommendation
Enforce a strong password policy with require_lowercase: true, adequate length, and mixed character types. Complement with defense in depth: enable MFA, apply rate limiting or lockout for failed attempts, and block common passwords. Review regularly to match business risk and user population.
Remediation
CLI
aws cognito-idp update-user-pool --user-pool-id <example_resource_id> --policies "PasswordPolicy={RequireLowercase=true}"Terraform
resource "aws_cognito_user_pool" "pool" {
name = "<example_resource_name>"
password_policy {
require_lowercase = true # Critical: enforces at least one lowercase character
}
}NativeIaC
Resources:
UserPool:
Type: AWS::Cognito::UserPool
Properties:
Policies:
PasswordPolicy:
RequireLowercase: true # Critical: requires at least one lowercase letter in passwordsOther
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.cognito.cognito_idp_client import cognito_idp_client
class cognito_user_pool_password_policy_lowercase(Check):
def execute(self):
findings = []
for pool in cognito_idp_client.user_pools.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=pool)
if pool.password_policy:
if pool.password_policy.require_lowercase:
report.status = "PASS"
report.status_extended = f"User pool {pool.name} has a password policy with a lowercase requirement."
else:
report.status = "FAIL"
report.status_extended = f"User pool {pool.name} does not have a password policy with a lowercase requirement."
else:
report.status = "FAIL"
report.status_extended = (
f"User pool {pool.name} has not a password policy set."
)
findings.append(report)
return findings