Skip to main content

Ensure Cognito User Pool Has Advanced Security Enabled

Overview

This check verifies that your Amazon Cognito User Pool has threat protection enabled in ENFORCED (full-function) mode. Advanced security features protect your users from credential stuffing, brute force attacks, and account takeovers by actively blocking risky sign-in attempts rather than just logging them.

Risk

Without advanced security enabled, your user pool is vulnerable to:

  • Credential stuffing attacks: Attackers can try stolen username/password combinations from other breaches
  • Brute force attacks: Repeated login attempts to guess passwords
  • Account takeovers: Unauthorized access to user accounts
  • Compromised credential use: Users unknowingly signing in with leaked passwords

When threat protection is disabled or set to AUDIT mode, risky sign-ins are only logged but not blocked, leaving your users exposed.

Remediation Steps

Prerequisites

You need:

  • Access to the AWS Console with permissions to modify Cognito User Pools, OR
  • AWS CLI configured with appropriate credentials
  • The User Pool ID of the affected resource

Important: Enabling advanced security features requires the Cognito Plus tier, which has additional costs. Review Cognito pricing before proceeding.

AWS Console Method

  1. Sign in to the AWS Console and navigate to Amazon Cognito
  2. In the left navigation, click User pools
  3. Select the user pool you want to secure
  4. Click the Threat protection tab
  5. If threat protection is not active, click Activate threat protection
    • You may be prompted to upgrade to the Plus tier if you are on the Essentials tier
  6. Under Enforcement mode, select Full function (this corresponds to ENFORCED mode)
  7. Configure the recommended settings:
    • Enable Compromised credentials protection to block sign-ins with known leaked passwords
    • Set up Adaptive authentication to require additional verification for risky sign-ins
  8. Click Save changes
AWS CLI (optional)

Use the following command to enable advanced security on an existing user pool:

aws cognito-idp update-user-pool \
--user-pool-id <your-user-pool-id> \
--user-pool-add-ons AdvancedSecurityMode=ENFORCED \
--region us-east-1

Replace <your-user-pool-id> with your actual User Pool ID (e.g., us-east-1_AbCdEfGhI).

Warning: The update-user-pool command requires you to pass the complete existing configuration to avoid resetting other settings to defaults. To safely update only the advanced security setting, first describe your current pool configuration:

aws cognito-idp describe-user-pool \
--user-pool-id <your-user-pool-id> \
--region us-east-1

Then include the relevant existing settings in your update command along with the new --user-pool-add-ons parameter.

CloudFormation (optional)

To create a new Cognito User Pool with advanced security enabled, or update an existing one managed by CloudFormation:

AWSTemplateFormatVersion: '2010-09-09'
Description: Cognito User Pool with Advanced Security Enabled

Parameters:
UserPoolName:
Type: String
Default: MySecureUserPool
Description: Name for the Cognito User Pool

Resources:
SecureUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: !Ref UserPoolName
UserPoolAddOns:
AdvancedSecurityMode: ENFORCED
AdminCreateUserConfig:
AllowAdminCreateUserOnly: false
AutoVerifiedAttributes:
- email
MfaConfiguration: OPTIONAL
Policies:
PasswordPolicy:
MinimumLength: 12
RequireLowercase: true
RequireNumbers: true
RequireSymbols: true
RequireUppercase: true

Outputs:
UserPoolId:
Description: User Pool ID
Value: !Ref SecureUserPool
UserPoolArn:
Description: User Pool ARN
Value: !GetAtt SecureUserPool.Arn

Deploy the stack:

aws cloudformation deploy \
--template-file template.yaml \
--stack-name cognito-secure-user-pool \
--region us-east-1
Terraform (optional)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "user_pool_name" {
description = "Name for the Cognito User Pool"
type = string
default = "my-secure-user-pool"
}

resource "aws_cognito_user_pool" "main" {
name = var.user_pool_name

user_pool_add_ons {
advanced_security_mode = "ENFORCED"
}

password_policy {
minimum_length = 12
require_lowercase = true
require_numbers = true
require_symbols = true
require_uppercase = true
temporary_password_validity_days = 7
}

mfa_configuration = "OPTIONAL"

auto_verified_attributes = ["email"]

admin_create_user_config {
allow_admin_create_user_only = false
}
}

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 enabling advanced security, verify the setting is active:

  1. In the AWS Console, go to Amazon Cognito > User pools
  2. Select your user pool
  3. Click the Threat protection tab
  4. Confirm that Enforcement mode shows Full function
CLI Verification
aws cognito-idp describe-user-pool \
--user-pool-id <your-user-pool-id> \
--region us-east-1 \
--query 'UserPool.UserPoolAddOns.AdvancedSecurityMode'

The output should return:

"ENFORCED"

Additional Resources

Notes

  • Cost consideration: Advanced security features require the Cognito Plus tier, which has additional per-monthly-active-user costs. Review pricing before enabling in production.
  • AUDIT vs ENFORCED: You can start in AUDIT mode to monitor risky sign-ins without blocking them, then switch to ENFORCED once you understand your baseline traffic patterns.
  • Existing users: Enabling advanced security does not disrupt existing user sessions. New sign-in attempts will be evaluated against the threat protection rules.
  • Compromised credentials: When enabled, Cognito checks passwords against known breach databases during sign-up and sign-in. Users with compromised passwords will be prompted to change them.
  • Adaptive authentication: Consider configuring step-up MFA for risky sign-ins to add an extra layer of protection without impacting low-risk users.