Currently I have my App deployed on Firebase and using AWS Amplify with AWS Cognito for authenticate users and Sessions
The security Team reported that is a Session HIjacking vulnerability.
# Used Cookie
[
{
"domain": "my_domain.firebaseapp.com",
"expirationDate": 1654892898,
"hostOnly": true,
"httpOnly": false,
"name": "IdToken",
"path": "/",
"sameSite": null,
"secure": false,
"session": false,
"storeId": null,
"value": "XXXXXXX"
}
]
# LocalStorage
{
"CognitoIdentityServiceProvider.MY_ID_CLIENT_APP.LastAuthUser": "MY_SAML_PROVIDER",
"CognitoIdentityServiceProvider.MY_ID_CLIENT_APP.MY_SAML_PROVIDER.accessToken": "XXXXX",
"amplify-redirected-from-hosted-ui": "true",
"CognitoIdentityServiceProvider.MY_ID_CLIENT_APP.MY_SAML_PROVIDER.idToken": "XXXXX",
"amplify-signin-with-hostedUI": "true",
"CognitoIdentityServiceProvider.MY_ID_CLIENT_APP.MY_SAML_PROVIDER.clockDrift": "0",
"CognitoIdentityServiceProvider.MY_ID_CLIENT_APP.MY_SAML_PROVIDER.refreshToken": "XXXXX"
}
My code uses:
//Verify Session
useEffect(() => {
const paths = queryString.parse(window.location.search)
if (!state.NotLogin) {
if (paths.code && paths.state) {
setloadHosted(true)
}
Auth.currentAuthenticatedUser().then(res=> {
let finalUser = ""
let usernameCognito = res.username.split("_")
if (usernameCognito.length === 2) {
finalUser = usernameCognito[1]
}
else {
finalUser = usernameCognito
}
sweetAlert(`Welcome, ${finalUser}`, "success")
Cookies.set('IdToken', res.signInUserSession.idToken.jwtToken, { expires: 1 })
actions({ type: "setState", payload: { ...state, username: finalUser } })
setloadHosted(false)
setShowOption(true)
})
}
else{
setShowOption(true)
}
}, [])
In principle, detecting session hijacking can be done by:
The (1) method, requires you to store the IP address of the sign in / up request in the created JWT / session token. On each subsequent request, you would check that the IP in the token is the same as the IP of the request. If not, you can return a 401. Whilst this method adds an extra layer of protection, it can result in false negatives / positives (For example, what if the user starts to use a VPN).
Method (2) is more robust, but much more complex to implement. In a nutshell, you need to change the refresh token on each use (Not sure if cognito has that), and if a previous refresh token is used after a new one is already issued, then it's a session theft. This has almost no false positives or negatives, assuming that the implementation is done correctly. Going into the implementation details in this answer would be difficult, so I am linking a blog: https://supertokens.com/blog/the-best-way-to-securely-manage-user-sessions
Finally, you can decrease the surface area of the attack vector:
If Cognito doesn't have some of these features, consider using a different solution for session management. In this case, you can consume the ID token sent by Cognito to create a new cookie based session for your app, and ideally this session should have all the security features.
Hope this helps!