IAM Password Policy Requires Symbol
Overview
This check verifies that your AWS account's password policy requires at least one special character (symbol) in IAM user passwords. Symbols include characters like ! @ # $ % ^ & * ( ) _ + - = [ ] { } | '.
A strong password policy is one of the simplest ways to protect your AWS account from unauthorized access.
Risk
Without a symbol requirement, passwords are easier to guess or crack. Attackers using automated tools can try millions of simple password combinations quickly. If an IAM user's password is compromised, the attacker gains access to your AWS resources with that user's permissions.
Remediation Steps
Prerequisites
You need one of the following:
- AWS Console access with permission to modify IAM settings (typically an administrator)
- AWS CLI installed and configured (for command-line method)
AWS Console Method
- Sign in to the AWS Management Console
- Go to IAM (search for "IAM" in the top search bar)
- In the left navigation, click Account settings
- In the Password policy section, click Edit
- Check the box for Require at least one non-alphanumeric character
- Click Save changes
That's it! The new policy applies to all future password changes.
AWS CLI (optional)
Run the following command to enable the symbol requirement:
aws iam update-account-password-policy \
--require-symbols \
--region us-east-1
Important: The update-account-password-policy command replaces your entire password policy. If you have other settings you want to keep, include them all in one command:
aws iam update-account-password-policy \
--minimum-password-length 14 \
--require-symbols \
--require-numbers \
--require-uppercase-characters \
--require-lowercase-characters \
--allow-users-to-change-password \
--max-password-age 90 \
--password-reuse-prevention 24 \
--region us-east-1
To see your current password policy first:
aws iam get-account-password-policy --region us-east-1
CloudFormation (optional)
AWS CloudFormation does not have a native resource type for IAM Account Password Policy. You need to use a Custom Resource backed by a Lambda function.
Here is a complete example:
AWSTemplateFormatVersion: '2010-09-09'
Description: IAM Account Password Policy with symbol requirement
Resources:
PasswordPolicyLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: IAMPasswordPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:UpdateAccountPasswordPolicy
- iam:DeleteAccountPasswordPolicy
Resource: '*'
PasswordPolicyLambda:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.12
Handler: index.handler
Role: !GetAtt PasswordPolicyLambdaRole.Arn
Timeout: 60
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
try:
iam = boto3.client('iam')
if event['RequestType'] in ['Create', 'Update']:
props = event['ResourceProperties']
iam.update_account_password_policy(
MinimumPasswordLength=int(props.get('MinimumPasswordLength', 14)),
RequireSymbols=props.get('RequireSymbols', 'true').lower() == 'true',
RequireNumbers=props.get('RequireNumbers', 'true').lower() == 'true',
RequireUppercaseCharacters=props.get('RequireUppercaseCharacters', 'true').lower() == 'true',
RequireLowercaseCharacters=props.get('RequireLowercaseCharacters', 'true').lower() == 'true',
AllowUsersToChangePassword=props.get('AllowUsersToChangePassword', 'true').lower() == 'true',
MaxPasswordAge=int(props.get('MaxPasswordAge', 90)),
PasswordReusePrevention=int(props.get('PasswordReusePrevention', 24))
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
print(f"Error: {e}")
cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})
AccountPasswordPolicy:
Type: Custom::PasswordPolicy
Properties:
ServiceToken: !GetAtt PasswordPolicyLambda.Arn
RequireSymbols: 'true'
RequireNumbers: 'true'
RequireUppercaseCharacters: 'true'
RequireLowercaseCharacters: 'true'
MinimumPasswordLength: '14'
MaxPasswordAge: '90'
PasswordReusePrevention: '24'
AllowUsersToChangePassword: 'true'
Deploy with:
aws cloudformation deploy \
--template-file password-policy.yaml \
--stack-name iam-password-policy \
--capabilities CAPABILITY_IAM \
--region us-east-1
Terraform (optional)
resource "aws_iam_account_password_policy" "strict" {
require_symbols = true
require_numbers = true
require_lowercase_characters = true
require_uppercase_characters = true
minimum_password_length = 14
password_reuse_prevention = 24
max_password_age = 90
allow_users_to_change_password = true
}
Apply with:
terraform init
terraform plan
terraform apply
Note: There can only be one password policy per AWS account. If a policy already exists, Terraform will update it.
Verification
After making changes, verify the policy is in place:
- Go to IAM > Account settings in the AWS Console
- Under Password policy, confirm that Require at least one non-alphanumeric character is checked
CLI verification
aws iam get-account-password-policy \
--query 'PasswordPolicy.RequireSymbols' \
--region us-east-1
Expected output: true
To see the full policy:
aws iam get-account-password-policy --region us-east-1
Additional Resources
- AWS IAM Password Policy Documentation
- AWS Security Best Practices for IAM
- CIS AWS Foundations Benchmark
Notes
- Existing users are not affected immediately: The new policy applies only when users change their passwords. Consider requiring a password reset if you need immediate compliance.
- One policy per account: AWS allows only one account-level password policy. Any changes replace the entire policy.
- Recommended full policy: For best security, combine symbols with other requirements: minimum 14 characters, uppercase, lowercase, numbers, and password reuse prevention.
- MFA is still essential: Even with a strong password policy, always enable multi-factor authentication (MFA) for all IAM users with console access.