Analyze Amazon Cognito sophisticated security intelligence to boost protection and visibility
As your organization looks to improve your security practices and posture, early detection and prevention of unauthorized activity becomes one of your main priorities quickly. The behaviors associated with unauthorized activity commonly follow patterns that you can analyze in order to create specific mitigations or feed data into your security monitoring systems.
<p>You are showed by this post how you can analyze security intelligence from <a href="https://aws.amazon.com/cognito/" target="_blank" rel="noopener noreferrer">Amazon Cognito</a> advanced security features logs by using AWS native services. You can use the intelligence data provided by the logs to increase your visibility into sign-in and sign-up activities from users, this can help you with monitoring, decision making, and to feed other security services in your organization, such as a web application firewall or security information and event management (SIEM) tool. The data can enrich available security feeds like fraud detection systems also, increasing protection for the workloads that you run on AWS.</p>
<h2>Amazon Cognito advanced security features overview</h2>
<p>Amazon Cognito provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in to apps with a user name and password directly, or through a third party such as social providers or standard enterprise providers through SAML 2.0/OpenID Connect (OIDC). Amazon Cognito includes additional protections for users that you manage in Amazon Cognito user pools. In particular, Amazon Cognito can add risk-based adaptive authentication and flag the use of compromised credentials also. For more information, see <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-compromised-credentials.html" target="_blank" rel="noopener noreferrer">Checking for compromised credentials</a> in the Amazon Cognito Developer Guide.</p>
<p>With adaptive authentication, Amazon Cognito examines each user pool sign-in attempt and generates a risk score for how likely the sign-in request is from an unauthorized user. Amazon Cognito examines a true number of factors, including whether the user has used the same device before or has signed in from the same location or IP address. A detected risk is rated as low, medium, or high, and you can determine what actions should be taken at each risk level. You can choose to allow or block the request, require a second authentication factor, or notify the user of the risk by email. Security teams and administrators can submit feedback on the risk through the API also, and users can submit feedback by using a link that is sent to the user’s email. The risk can be improved by this feedback calculation for future attempts.</p>
<p>To add advanced security features to your existing Amazon Cognito configuration, you can get started by using the steps for <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html" target="_blank" rel="noopener noreferrer">Adding advanced security to a user pool</a> in the Amazon Cognito Developer Guide. Note that there is an additional charge for advanced security features, as described on our <a href="https://aws.amazon.com/cognito/pricing/" target="_blank" rel="noopener noreferrer">pricing page</a>. These features are applicable only to native Amazon Cognito users; they aren’t applicable to federated users who sign in with an external provider.</p>
<h2>Solution architecture</h2>
<div id="attachment_27225" class="wp-caption aligncenter">
<img aria-describedby="caption-attachment-27225" src="https://infracom.com.sg/wp-content/uploads/2022/10/img1-1.png" alt="Figure 1: Solution architecture" width="760" class="size-full wp-image-27225">
<p id="caption-attachment-27225" class="wp-caption-text">Figure 1: Solution architecture</p>
</div>
<p>Figure 1 shows the high-level architecture for the advanced security solution. When an Amazon Cognito sign-in event is recorded by <a href="https://aws.amazon.com/cloudtrail/" target="_blank" rel="noopener noreferrer">AWS CloudTrail</a>, an < is used by the solution;a href="https://aws.amazon.com/eventbridge/" target="_blank" rel="noopener noreferrer">Amazon EventBridge</a> rule to send the event to an <a href="https://aws.amazon.com/sqs/" target="_blank" rel="noopener noreferrer">Amazon Simple Queue Service (Amazon SQS)</a> batch and queue it, to be processed by an < then;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener noreferrer">AWS Lambda</a> function. The Lambda function uses the event information to pull the sign-in security information and send it as logs to an <a href="https://aws.amazon.com/s3/" target="_blank" rel="noopener noreferrer">Amazon Simple Storage Service (Amazon S3)</a> < and bucket;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html" target="_blank" rel="noopener noreferrer">Amazon CloudWatch Logs</a>.</p>
<h3>Considerations and prerequisites for this solution</h3>
<p>This solution assumes that you are using Amazon Cognito with advanced security features already enabled, the solution does not create a user pool and does not activate the advanced security features on an existing one.</p>
<p>The following list describes some limitations that you should be aware of for this solution:</p>
<ol>
<li>This solution does not apply to events in the hosted UI, but the same architecture can be adapted for that environment, with some noticeable changes to the events processor.</li>
<li>The Amazon Cognito advanced security features support only native users. This solution is not applicable to federated users.</li>
<li>The admin API used in this solution has a default rate limit of 30 requests per second (RPS). If you have a higher rate of authentication attempts, this API call might be throttled and you will need to implement a re-try pattern to confirm that your requests are processed.</li>
</ol>
<h2>Implement the solution</h2>
<p>You can deploy the solution by using the following < automatically;a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener noreferrer">AWS CloudFormation</a> template.</p>
<p>Choose the following <strong>Launch Stack</strong> button to launch a CloudFormation stack in your account and deploy the solution.</p>
<p><a href="https://aws.amazon.com/blogs/security/analyze-amazon-cognito-advanced-security-intelligence-to-improve-visibility-and-protection/URL%20for%20link%20goes%20here" rel="noopener noreferrer" target="_blank"><img src="https://d2908q01vomqb2.cloudfront.net/22d200f8670dbdb3e253a90eee5098477c95c23d/2019/06/05/launch-stack-button.png" alt="Select this image to open a link that starts building the CloudFormation stack" width="190" height="36" class="aligncenter size-full wp-image-10149"></a></p>
<p>You’ll be redirected to the CloudFormation service in the US East (N. Virginia) Region, which is the default AWS Region, to deploy this solution. The Region can be changed by you to align it to where your Cognito User Pool is running.</p>
<p>This template shall create multiple cloud resources including, but not limited to, the following:</p>
<ul>
<li>An EventBridge rule for sending the Amazon Cognito events</li>
<li>An Amazon SQS queue for sending the events to Lambda</li>
<li>A Lambda function for getting the advanced security information based on the authentication events from CloudTrail</li>
<li>An S3 bucket to store the logs</li>
</ul>
<p>In the wizard, you’ll be asked to modify or provide one parameter, the existing Cognito user pool ID. This value can be got by you from the <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html" target="_blank" rel="noopener noreferrer">Amazon Cognito console</a> or <a href="https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/list-user-pools.html" target="_blank" rel="noopener noreferrer">the Cognito API</a>.</p>
<p>Now, let’s break down each component of the solution in detail.</p>
<h3>Sending the authentication events from CloudTrail to Lambda</h3>
<p>Cognito advanced security features supports the CloudTrail events: SignUp, ConfirmSignUp, ForgotPassword, ResendConfirmationCode, RespondToAuthChallenge and initiateauth. This solution shall focus on the sign-in event <span>InitiateAuth</span> as an example.</p>
<p>The solution creates an EventBridge rule that will run when an event is identified in CloudTrail and send the event to an SQS queue. This is useful so that events can be batched up and decoupled for Lambda to process.</p>
<p>The EventBridge rule uses Amazon SQS as a target. The solution creates the queue and uses the default settings, with the exception that <strong>Receive message wait time</strong> is set to 20 seconds for long polling. For more information about long polling and how to set up an SQS queue manually, see <a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html#sqs-long-polling" target="_blank" rel="noopener noreferrer">Consuming messages using long polling</a> in the Amazon SQS Developer Guide.</p>
<p>When the SQS queue receives the messages from EventBridge, these are sent to Lambda for processing. Let’s now focus on understanding how this information is processed by the Lambda function.</p>
<h3>Using Lambda to process Amazon Cognito advanced security features information</h3>
<p>In order to get the advanced security features evaluation information, you need authentication details that can only be obtained by using the Amazon Cognito identity provider (IdP) API call <a href="https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminListUserAuthEvents.html" target="_blank" rel="noopener noreferrer">admin_list_user_auth_events</a>. This API call requires a username to fetch all the authentication event details for a specific user. For security reasons, the username is not logged in CloudTrail and must be obtained by using other event information.</p>
<p>You can use the Lambda function in the sample solution to get this given information. It’s composed of three main sequential actions:</p>
<ol>
<li>The Lambda function gets the sub identifiers from the authentication events recorded by CloudTrail.</li>
<li>Each sub identifier is used to get the user name through an API call to <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.list_users" target="_blank" rel="noopener noreferrer">list_users</a>.</li>
<li>3. The sample function retrieves the last five authentication event details from advanced security features for each of these users by using the <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.admin_list_user_auth_events" rel="noopener noreferrer" target="_blank">admin_list_user_auth_events</a> API call. You can modify the function to retrieve a different number of events, or use other criteria such as a timestamp or a specific time period.</li>
</ol>
<h4><em>Getting the user name information from a CloudTrail event</em></h4>
<p>The following sample authentication event shows a <span>sub</span> identifier in the CloudTrail event information, shown as <span>sub</span> under <span>additionalEventData</span>. With this <span>sub</span> identifier, the < can be used by you;span>ListUsers</span> API call from the Cognito IdP SDK to get the user name details.</p>
<div class="hide-language">
<pre><code class="lang-text">
“eventVersion”: “1.XX”,
“userIdentity”:
“type”: “Unknown”,
“principalId”: “Anonymous”
,
“eventTime”: “2022-01-01T11:11:11Z”,
“eventSource”: “cognito-idp.amazonaws.com”,
“eventName”: “InitiateAuth”,
“awsRegion”: “us-east-1”,
“sourceIPAddress”: “xx.xx.xx.xx”,
“userAgent”: “Mozilla/5.0 (xxxx)”,
“requestParameters”:
“authFlow”: “USER_SRP_AUTH”,
“authParameters”: “HIDDEN_DUE_TO_SECURITY_REASONS”,
“clientMetadata”: ,
“clientId”: “iiiiiiiii”
,
“responseElements”:
“challengeName”: “PASSWORD_VERIFIER”,
“challengeParameters”:
“SALT”: “HIDDEN_DUE_TO_SECURITY_REASONS”,
“SECRET_BLOCK”: “HIDDEN_DUE_TO_SECURITY_REASONS”,
“USER_ID_FOR_SRP”: “HIDDEN_DUE_TO_SECURITY_REASONS”,
“USERNAME”: “HIDDEN_DUE_TO_SECURITY_REASONS”,
“SRP_B”: “HIDDEN_DUE_TO_SECURITY_REASONS”
,
“additionalEventData”:
“sub”: “11110b4c-1f4264cd111”
,
“requestID”: “xxxxxxxx”,
“eventID”: “xxxxxxxxxx”,
“readOnly”: false,
“eventType”: “AwsApiCall”,
“managementEvent”: true,
“recipientAccountId”: “xxxxxxxxxxxxx”,
“eventCategory”: “Management”
<h4><em>Listing authentication events information</em></h4>
After the Lambda function obtains the username, it can use the Cognito IdP API call < then;span>admin_list_user_auth_events</span> to get the advanced security feature risk evaluation information for each of the authentication events for that user. Let’s look into the details of that evaluation.</p>
<p>The authentication event information from Amazon Cognito advanced security provides information for each of the categories evaluated and logs the results. Those results can then be used to decide whether the authentication attempt information is useful for the security team to be notified or take action. It’s recommended that you limit the true number of events returned, in order to keep performance optimized.</p>
<p>The following sample event shows some of the risk information provided by advanced security features; the options for the response syntax can be found in the <span>CognitoIdentityProvider</span> <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.admin_list_user_auth_events" target="_blank" rel="noopener noreferrer">API documentation</a>.</p>
<div class="hide-language">
<pre><code class="lang-text">}
]
at the bottom, so
“AuthEvents”: [
“EventId”: “1111111”,
“EventType”: “SignIn”,
“CreationDate”: 111111.111,
“EventResponse”: “Pass”,
“EventRisk”:
“RiskDecision”: “NoRisk” ,
“CompromisedCredentialsDetected” : false
,
“ChallengeResponses”: [
“ChallengeName”: “Password”,
“ChallengeResponse”: “Success”
],
“EventContextData”:
“IpAddress”: “72.xx.xx.xx”,
“DeviceName”: “Firefox xx
“City”: “Axxx”,
“Country”: “United States”
]
The event information that is returned includes the details that are highlighted in this sample event, such as CompromisedCredentialsDetected , RiskDecision , and RiskLevel , which you can evaluate to decide whether the given information can be used to enrich other security monitoring services.
Logging the authentication events information
You can use a Lambda extensions layer to send logs to an S3 bucket. Lambda still sends logs to Amazon CloudWatch Logs , but you can disable this activity by removing the required permissions to CloudWatch on the Lambda execution role. For more details on how to set this up, see Using AWS Lambda extensions to send logs to custom destinations .
Figure 2 shows an example of a log sent by Lambda. It includes execution information that is logged by the extension, as well as the given information returned from the authentication evaluation by advanced security features.
Note that the detailed authentication information in the Lambda execution log is the same as the preceding sample event. You can further enhance the information provided by the Lambda function by modifying the function code and logging more information during the execution, or by filtering the logs and focusing only on compromised or high-risk login attempts.
After the logs are in the S3 bucket, different applications and tools can use this information to perform automated security actions and configuration updates or provide further visibility. You can query the data from Amazon S3 by using Amazon Athena , feed the data to other services such as Amazon Fraud Detector as described in this post , mine the data by using artificial intelligence/machine learning (AI/ML) managed tools like AWS Lookout for Metrics , or enhance visibility with AWS WAF .
Sample scenarios
You can start to gain insights into the security information provided by this solution in an existing environment by querying and visualizing the log data directly by using CloudWatch Logs Insights . For detailed information about how you can use CloudWatch Logs Insights with Lambda logs, see the blog post Operating Lambda: Using CloudWatch Logs Insights .
The CloudFormation template deploys the CloudWatch Logs Insights queries. You can view the queries for the sample solution in the Amazon CloudWatch console , under Queries .
To access the queries in the CloudWatch console
- In the CloudWatch console , under Logs , choose Insights .
- Choose Select log group(s) . In the drop-drown list, select the Lambda log group.
- The query box should show the pre-created query. Choose Run query . You should see the query results in the bottom-right panel then.
- (Optional) Choose Add to dashboard to add the widget to a dashboard.
CloudWatch Logs Insights discovers the fields in the auth event log automatically. As shown in Figure 3, you can see the available fields in the right-hand side Discovered fields pane, which includes the Amazon Cognito information in the event.
The first query, shown in the following code snippet, will help you get a view of the true number of requests per IP, where the advanced security features have determined the risk decision as Account Takeover and the CompromisedCredentialsDetected as true .
You can view the total results of the query as a table or graph, as shown in Figure 4.
Using the same approach and the convenient access to the fields for query, you can explore another use case, using the following query, to view the number of requests per IP for each type of event (SignIn, SignUp, and forgot password) where the risk level was high .
Figure 5 shows the total results for this EventType query.
In the final sample scenario, you can look at event context data and query for the source of the events for which the risk level was high .
Figure 6 shows the total results for this RiskLevel query.
As you can see, there are many ways to mix and match the filters to extract deep insights, depending on your specific needs. These examples can be used by you as a base to build your own queries.
Conclusion
In this post, you learned how to use security intelligence information provided by Amazon Cognito through its advanced security features to improve your security posture and practices. You used an advanced security solution to retrieve valuable authentication information using CloudTrail logs as a source and a Lambda function to process the events, send this evaluation information in the form of a log to CloudWatch Logs and S3 for use as an additional security feed for wider organizational monitoring and visibility. In a set of sample use cases, you explored how to use CloudWatch Logs Insights to and conveniently access this information quickly, aggregate it, gain deep use and insights it to take action.
To learn more, see the blog post How to Use New Advanced Security Features for Amazon Cognito User Pools .
If you have feedback about this post, submit comments in the Comments section below.
Want more AWS Security news? Follow us on Twitter .
<!-- '"` -->
You must be logged in to post a comment.