Skip to main content

Ensure Amazon Cognito User Pool Blocks Potential Malicious Sign-In Attempts

Overview

This check verifies that your Amazon Cognito user pool has threat protection enabled with adaptive authentication configured to block risky sign-in attempts. When enabled, Cognito evaluates each login attempt and automatically blocks those that appear suspicious or malicious.

Risk

Without adaptive authentication blocking enabled, attackers who obtain or guess user credentials can:

  • Take over user accounts
  • Access sensitive application data
  • Modify user credentials and lock out legitimate users
  • Escalate privileges within your application
  • Move laterally to other connected systems

Remediation Steps

Prerequisites

You need:

  • AWS Console access with permissions to modify Cognito user pools
  • Your user pool must be on the Plus tier (threat protection is not available on Lite tier)
Required IAM permissions

Your IAM user or role needs these permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-idp:DescribeUserPool",
"cognito-idp:UpdateUserPool",
"cognito-idp:SetRiskConfiguration",
"cognito-idp:DescribeRiskConfiguration"
],
"Resource": "arn:aws:cognito-idp:*:*:userpool/*"
}
]
}

AWS Console Method

  1. Open the Amazon Cognito console
  2. Select your user pool from the list
  3. Click the Security tab in the left navigation
  4. Under Threat protection, click Edit
  5. For Threat protection mode, select Full function (this enforces protection)
  6. In the Automatic risk response section, configure:
    • High risk: Set to Block sign-in
    • Medium risk: Set to Block sign-in
    • Low risk: Set to Block sign-in
  7. Optionally configure Compromised credentials to block sign-ins when passwords are found in breach databases
  8. Click Save changes
AWS CLI (optional)

Step 1: Enable threat protection on your user pool

First, update your user pool to enable advanced security in ENFORCED mode:

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

Step 2: Configure risk responses to block malicious sign-ins

Set up the risk configuration to block at all risk levels:

aws cognito-idp set-risk-configuration \
--region us-east-1 \
--user-pool-id <your-user-pool-id> \
--account-takeover-risk-configuration '{
"Actions": {
"HighAction": {"EventAction": "BLOCK", "Notify": true},
"MediumAction": {"EventAction": "BLOCK", "Notify": true},
"LowAction": {"EventAction": "BLOCK", "Notify": true}
}
}' \
--compromised-credentials-risk-configuration '{
"EventFilter": ["SIGN_IN", "SIGN_UP", "PASSWORD_CHANGE"],
"Actions": {"EventAction": "BLOCK"}
}'

Replace <your-user-pool-id> with your actual user pool ID (format: us-east-1_XXXXXXXXX).

CloudFormation (optional)

Use this CloudFormation template to create a new user pool with threat protection enabled, or reference it for updating existing resources:

AWSTemplateFormatVersion: '2010-09-09'
Description: Cognito User Pool with threat protection enabled

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

Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: !Ref UserPoolName
UserPoolAddOns:
AdvancedSecurityMode: ENFORCED

RiskConfiguration:
Type: AWS::Cognito::UserPoolRiskConfigurationAttachment
Properties:
UserPoolId: !Ref CognitoUserPool
ClientId: ALL
AccountTakeoverRiskConfiguration:
Actions:
HighAction:
EventAction: BLOCK
Notify: true
MediumAction:
EventAction: BLOCK
Notify: true
LowAction:
EventAction: BLOCK
Notify: true
CompromisedCredentialsRiskConfiguration:
Actions:
EventAction: BLOCK
EventFilter:
- SIGN_IN
- SIGN_UP
- PASSWORD_CHANGE

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 with:

aws cloudformation deploy \
--region us-east-1 \
--template-file template.yaml \
--stack-name cognito-secure-pool \
--parameter-overrides UserPoolName=MySecureUserPool
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"
}

variable "notification_email_from" {
description = "Email address for sending notifications"
type = string
default = "no-reply@example.com"
}

variable "notification_reply_to" {
description = "Reply-to email address for notifications"
type = string
default = "support@example.com"
}

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

user_pool_add_ons {
advanced_security_mode = "ENFORCED"
}
}

resource "aws_cognito_risk_configuration" "main" {
user_pool_id = aws_cognito_user_pool.main.id

account_takeover_risk_configuration {
notify_configuration {
source_arn = aws_cognito_user_pool.main.arn
from = var.notification_email_from
reply_to = var.notification_reply_to
}

actions {
high_action {
event_action = "BLOCK"
notify = true
}
medium_action {
event_action = "BLOCK"
notify = true
}
low_action {
event_action = "BLOCK"
notify = true
}
}
}

compromised_credentials_risk_configuration {
actions {
event_action = "BLOCK"
}
event_filter = ["SIGN_IN", "SIGN_UP", "PASSWORD_CHANGE"]
}
}

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 with:

terraform init
terraform apply

Verification

After making changes, verify that threat protection is correctly configured:

  1. In the Cognito console, go to your user pool
  2. Click the Security tab
  3. Under Threat protection, confirm:
    • Mode shows Full function
    • All risk levels (High, Medium, Low) are set to Block sign-in
CLI verification

Check the user pool's advanced security mode:

aws cognito-idp describe-user-pool \
--region us-east-1 \
--user-pool-id <your-user-pool-id> \
--query 'UserPool.UserPoolAddOns.AdvancedSecurityMode'

Expected output: "ENFORCED"

Check the risk configuration:

aws cognito-idp describe-risk-configuration \
--region us-east-1 \
--user-pool-id <your-user-pool-id> \
--query 'RiskConfiguration.AccountTakeoverRiskConfiguration.Actions'

Expected output should show BLOCK for HighAction, MediumAction, and LowAction.

Additional Resources

Notes

  • Pricing: Threat protection is a paid feature available only on the Cognito Plus tier. Review Cognito pricing before enabling.
  • User impact: Blocking sign-ins at all risk levels provides maximum security but may occasionally block legitimate users. Consider starting with Medium and High only, then adding Low after monitoring for false positives.
  • Notifications: When Notify is enabled, users receive emails about blocked sign-in attempts. Ensure your user pool has email configured.
  • Multi-factor authentication (MFA): For additional protection, consider enabling MFA as a complement to threat protection.
  • IP allowlisting: If you have known trusted IP ranges, you can configure IP exceptions in the risk configuration to reduce false positives.