HttpOnly Cookies with AWS Cognito - amazon-web-services

I am using the amazon-cognito-identity-js SDK for user authentication. The CookieStorage object only takes domain, path, expires, and secure configurations. Is it possible to configure the authentication response to set the tokens in an HttpOnly cookie?

See Set a cookie to HttpOnly via Javascript. It is not possible for JavaScript to set httpOnly cookies, so amazon-cognito-identity-js can't do that either.
If you use the hosted sign-in/up pages, then Cognito will put httpOnly cookies on your client (server side). But those cookies don't contain JWT's.

Found this, from the discussion it looks like httpOnly cookies are not something AWS Cognito currently supports (which is really surprising)
https://github.com/aws-amplify/amplify-js/issues/3224
Note: the discussion is around AWS amplify but httpOnly cookies can only be set by the server for the client, so it shouldn't matter what client library is being used.

You can set HttpOnly cookie via express js or any other server.
I created a wrapper, an "identity service" sor of for AWS Cognito, that returns HttpOnly Cookies, it is easily achieveable since cognito comes with jwt authentication out of the box.
Note that the project was originally created to support, nuxt/next js in case you want other structure just change the endpoints.
https://github.com/cnikolov/aws-cognito-http

Related

Remove grafana cookie for user logout API

I’m using grafana HTTP API to build a front-end application on grafana.
User authentication is with the basic Auth model (default grafana authentication). I need the logout API, which cause grafana_session cookie expire.
I can not remove the grafana_session cookie from my scripts, because the httpOnly flag is on. Could you please help me to handle the user logout?
The only grafana configs that I've changed are two bellow configs:
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
cookie_samesite = none
# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. d$
allow_embedding = true
I found the solution and share it here to help if anybody had the same question.
As Jan said in the comment, Cookies are for the UI auth, and are set from the server. The HttpOnly flag makes cookies secure among the risk of cross-site scripting (XSS) and can not be deleted or overwritten from js scripts.
Grafana's default authentication uses the grafana_session cookie, which is an HttpOnly cookie. So If anybody else needs to know how we can delete the grafana_session cookie for user signout, you should only call /logout endpoint.
axios.get('http://localhost:3000/logout')
It will automatically set the cookie in request header, which will delete geafana_session token and user needs to login for the next requests.
headers: {
Cookie: 'grafana_session=; Path=/; Max-Age=0; HttpOnly; SameSite=Lax'
}
Following links helped me out to understand the HttpOnly cookies. May be useful for others:
https://stackoverflow.com/a/1085792/16994002
https://security.stackexchange.com/questions/211356/delete-secure-cookie-using-javascript
https://www.sjoerdlangkemper.nl/2020/05/27/overwriting-httponly-cookies-from-javascript-using-cookie-jar-overflow/

Using JWT authentication with Django/DRF and Storing JWTs in HttpOnly Cookies

I am trying to build a web app using Django and DRF at the back-end and ReactJs at the front end and I want to keep them separate (i.e. avoid Server Side Rendering).For authentication purposes, I want to employ JWT and I am using djangorestframework-jwt for that. I have read it at several places that it is not secure to store JWTs in the local storage so I am trying to use HttpOnly cookies for that. One can achieve that by configuring the django server to send HttpOnly by overriding the following default settings of the drf-jwt package in the settings.py file of your project JWT_AUTH = { 'JWT_AUTH_COOKIE': '<cookie name>', } which is set to none by default. The server sends the httpOnly cookie as anticipated but there are a few issues I am facing:
1.Same Domain Restraint
I am aware that httpOnly cookies wont be attached to the request headers unless the request is being made to the server which is hosted on the some domain. In my case I am using localhost:8000 for django and localhost:3000 for my react project so the browser doesnt attach the cookie as the request is made to a different port. I tried running both app on port 3000 simultaneously, and the browser did attach the cookie in the header and I did get the a 302 response from the server. However, it opened door to all sorts of problems due domain clash. I reckon I can solve this problem using nginx reverse proxy or something like that but I am not sure about it. Do guide me how can I serve both apps on the same host during the development.
2. Token Refresh Problem
When I refer to the view setup to refresh the token, I run into a bad request error even when the browser does attach the cookie along the request header. This is the server response in the browser
{"token":["This field is required."]}
Thanks if for reading it all the way down here!
In order for things to be secure:
You need CORS (Quickstart: CORS_ALLOWED_HOSTS=["http://localhost:3000"], CORS_ALLOW_CREDENTIALS=True)
The short-lived token (session) cookie (5-15mins), should NOT have HTTP-ONLY setting
The refresh token cookie SHALL have HTTP-ONLY setting
Then your basic flow is:
On login Django creates session token and sends it
Your SPA reads the cookie and adds its value to the authorization header (Authorization: JWT ...token...)
Any request to Django should be made with that Authorization header
The refresh flow is:
Send a request to the refresh token endpoint following the documentation of the library you use
Django then reads the HTTP-ONLY cookie and verifies it
If valid, Django sends a new refresh token as HTTP-ONLY cookie along with a new short-lived token session cookie
Once the refresh token has expired, you log the user out.
An article here goes into detail using GraphQL, but the cookie part and handling of most of the frontend code you should be able to adapt to REST.

Safari cookie in iframe

Latest safari update block 3rd-party cookies in iframe. ( https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/ )
They offer several solutions to resolve it. I have tried to implement Storage Access API solution, but do like the result.
Can anyone give a hint or a sample flow without technical details on how to implement this:
Option 1: OAuth 2.0 Authorization with which the authenticating domain (in your case, the third-party
that expects cookies) forwards an authorization token to your website which you consume and use to
establish a first-party login session with a server-set Secure and HttpOnly cookie.
firstparty.com has 3rdparty.com in iframe. According to option 1 3rdparty.com authorize via OAuth, receive token. But what does it mean to "forward token to your website to establish login session"? Should 3rdparty.com run login routine as first-party in separate window?
what they are referring to is still having the cookie be a first party (on your website). for example:
user follows this flow:
go to website.com
redirected to oauthSite.com for authentication
ouathSite.com redirects back to website.com with token (or code)
website.com sets token locally on server side code
user now has secure (https only) and HttpOnly (inaccessible to the JavaScript) cookie token that can be used for stateless interactions with website.com
This site seems to go thought the flows quite well:
https://medium.com/#darutk/diagrams-and-movies-of-all-the-oauth-2-0-flows-194f3c3ade85

SameSite attribute in cookies

I have a website a.com that has third party app point to apps.b.com. When I login to a.com, I'm also authenticated to apps.b.com in the background using the same credentials. This is so the users do not have to login to access apps.b.com. I understand that browser sends all the cookies to apps.b.com when making the request to it. This is how it works now. Reading the article https://web.dev/samesite-cookies-explained/ in regards to SameSite attribute, it appears apps.b.com is third party site.
Now do I have to configure web server on a.com to set the cookie to SameSite=none;Secure OR do I have to set the SameSite=none;Secure on web server on apps.b.com?
Any time you are making a cross-site request that needs cookies, then those cookies need to be marked SameSite=None; Secure.
So, for example if the user is on a.com and you have an <iframe> or fetch() to apps.b.com that expects cookies, then the apps.b.com cookies need SameSite=None; Secure.
Vice versa, if the user is on apps.b.com and you are making requests to a.com to check their auth status by relying on the a.com cookies, then those cookies need SameSite=None; Secure.
Essentially the pattern you're looking for is when the site in the browser location bar is different to the site that needs the cookies, then those are the cookies that need marking. So, depending on your set up, it may be one or both.

How to persist JsessionID in wso2 identity server

Currently we are using wso2 IS 4.1.0 version, entitlements service for policy decisions. As entitlement service is a secured service we authenticate and get the cookie then pass the cookie along with the entitlements service requests. we are using jsessionid cookie and ran into a situation where if the wso2 is goes down we have to restart our app as it has a stale cookie we refresh the cookie on a time interval every 15 min. Is there a way in wso2 is to persist the cookie if it get restarted. we tried commenting the inside wso2is-4.1.0\repository\conf\tomcat\carbon\META-INF.
Can you suggest on how we can configure for persistence of jsessionid cookies in wso2is
Thanks
Kishore
User session (jsessionid) is not persisted in server side. So you can re-authenticated after 15min and get a new jsessionid. (If you received an authenticate failure, you can re authenticated). you need to implement PEP in such way.
If you are using basic authentication to authenticate with entitlement service. You can send both cookie (jsessionid) and basic auth header... if cookie is valid it would be authenticate with cookie, if not use basic auth headers and returns the new cookie to client. you can find some java code for this here.. but this is not for entitlement service but you can use....
[1] https://github.com/soasecurity/soasecurity/blob/master/user-mgt/client/remote-user-400/src/main/java/org/soa/security/sample/user/mgt/SampleUserRoleMgtClient.java