Ensure Cognito User Pool Password Policy Requires Symbols
Overview
This check verifies that your Amazon Cognito user pool password policy requires at least one special character (symbol) in user passwords. Symbols include characters like !@#$%^&*().
Requiring symbols significantly increases password complexity, making passwords harder to guess or crack through automated attacks.
Risk
Without a symbol requirement, passwords have lower entropy and are more vulnerable to:
- Brute-force attacks: Attackers can try more password combinations faster
- Credential stuffing: Reused simple passwords are easier to exploit
- Dictionary attacks: Common words without symbols are quickly guessed
If an attacker compromises a Cognito user account, they could access your application, modify user data, or escalate privileges depending on how your app uses Cognito.
Remediation Steps
Prerequisites
You need permission to modify Cognito user pools in your AWS account. Specifically, you need the cognito-idp:UpdateUserPool permission.
AWS Console Method
- Open the Amazon Cognito console
- Select your User pool from the list
- Go to the Sign-in experience tab
- Scroll down to Password policy and click Edit
- Under Password requirements, check the box for Require special character
- Click Save changes
Note: This change only affects new passwords. Existing users keep their current passwords until they change them.
AWS CLI
Use the update-user-pool command to enable the symbol requirement.
Important: The update-user-pool command replaces the entire policy configuration. If you don't specify other password settings, they revert to defaults. Always include your complete desired configuration.
First, get your current user pool configuration to preserve existing settings:
aws cognito-idp describe-user-pool \
--user-pool-id <your-user-pool-id> \
--region us-east-1 \
--query 'UserPool.Policies.PasswordPolicy'
Then update with all your desired settings:
aws cognito-idp update-user-pool \
--user-pool-id <your-user-pool-id> \
--region us-east-1 \
--policies '{
"PasswordPolicy": {
"MinimumLength": 12,
"RequireUppercase": true,
"RequireLowercase": true,
"RequireNumbers": true,
"RequireSymbols": true,
"TemporaryPasswordValidityDays": 7
}
}'
Replace <your-user-pool-id> with your actual user pool ID (format: us-east-1_xxxxxxxxx).
Minimal update (only sets symbol requirement, other settings go to defaults):
aws cognito-idp update-user-pool \
--user-pool-id <your-user-pool-id> \
--region us-east-1 \
--policies "PasswordPolicy={RequireSymbols=true}"
CloudFormation
Add or update the Policies property in your AWS::Cognito::UserPool resource:
AWSTemplateFormatVersion: '2010-09-09'
Description: Cognito User Pool with strong password policy requiring symbols
Parameters:
UserPoolName:
Type: String
Description: Name of the Cognito User Pool
Default: MyUserPool
Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: !Ref UserPoolName
Policies:
PasswordPolicy:
MinimumLength: 12
RequireUppercase: true
RequireLowercase: true
RequireNumbers: true
RequireSymbols: true
TemporaryPasswordValidityDays: 7
Outputs:
UserPoolId:
Description: The ID of the Cognito User Pool
Value: !Ref CognitoUserPool
UserPoolArn:
Description: The ARN of the Cognito User Pool
Value: !GetAtt CognitoUserPool.Arn
Deploy the stack:
aws cloudformation deploy \
--template-file template.yaml \
--stack-name cognito-secure-password-policy \
--region us-east-1
Terraform
Configure the password_policy block in your aws_cognito_user_pool resource:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
variable "user_pool_name" {
description = "Name of the Cognito User Pool"
type = string
default = "my-user-pool"
}
resource "aws_cognito_user_pool" "main" {
name = var.user_pool_name
password_policy {
minimum_length = 12
require_uppercase = true
require_lowercase = true
require_numbers = true
require_symbols = true
temporary_password_validity_days = 7
}
tags = {
Environment = "production"
}
}
output "user_pool_id" {
description = "The ID of the Cognito User Pool"
value = aws_cognito_user_pool.main.id
}
output "user_pool_arn" {
description = "The ARN of the Cognito User Pool"
value = aws_cognito_user_pool.main.arn
}
Apply the configuration:
terraform init
terraform plan
terraform apply
Verification
After making the change, confirm the symbol requirement is enabled:
- In the Cognito console, navigate to your user pool
- Go to Sign-in experience > Password policy
- Verify Require special character is checked
CLI Verification
aws cognito-idp describe-user-pool \
--user-pool-id <your-user-pool-id> \
--region us-east-1 \
--query 'UserPool.Policies.PasswordPolicy.RequireSymbols'
Expected output: true
To see the complete password policy:
aws cognito-idp describe-user-pool \
--user-pool-id <your-user-pool-id> \
--region us-east-1 \
--query 'UserPool.Policies.PasswordPolicy'
Additional Resources
- AWS Cognito User Pool Password Policy
- AWS Cognito Security Best Practices
- Prowler Check Documentation
Notes
- Existing users: Password policy changes only apply to new passwords. Existing users can continue using their current passwords until they reset them. Consider implementing a password rotation policy.
- User experience: Requiring symbols may cause some friction for users. Balance security with usability by providing clear password requirements during registration.
- Recommended settings: For strong security, combine symbol requirements with:
- Minimum length of 12+ characters
- Uppercase and lowercase letters required
- Numbers required
- Password history to prevent reuse
- Compliance: This check maps to frameworks including C5, KISA-ISMS-P, and NIS2.