In memory JWT for API auth with HTTP-only cookie for sessions?

I’ve spent a while reading about this, and I know it’s a common topic, but I was hoping to get some feedback on my authentication approach.

I have an SPA. It needs to authenticate to 1) my application backend and 2) some APIs on AWS. I’m using cognito to authenticate user credentials.

My idea on approaching this is as follows:

  1. User authenticates via AWS Cognito API
  2. Receives JWT
  3. Keeps JWT in memory only (no local storage — XSS)
  4. Passes JWT to application backend
  5. Backend sets HTTP-only secure cookie on the client, STORING the JWT inside this cookie.
  6. Cookie is used to maintain sessions with the app backend
  7. In-memory JWT is used to authenticate with AWS APIs

This is fine-and-dandy, but when the user closes browser or switches tabs, they won’t have the JWT in memory. However, they’ll still have the session cookie. So my thought is that it will ask the application server for the JWT (inside the cookie) before hitting the AWS APIs.

In this fashion, I have a secure HTTP-only cookie that maintains sessions with my app server, and I also have the JWT to authenticate with the AWS APIs. If the user has a valid session cookie, it means they should allowed to have the JWT contained within it.

My only concern with this is that it seems a little circular. JWT authenticates to receive cookie, which authenticates in the future to receive a refreshed JWT. Otherwise, I think it seems pretty solid.

Thoughts?

Are the trade offs for putting an auth token in an http-only cookie for an SPA worth it?

I’ve been building a web app (rails api + react SPA) for learning / fun and have been researching authentication. The most commonly recommended approach for authenticating SPAs that I have read is to put the auth token (such as a JWT) in a secure HTTP-only cookie to protect from XSS. This seems to have a couple of consequences:

  • We now have to handle CSRF since we are using cookie authentication
  • Since it’s an SPA we can’t protect against CSRF until the user is logged in, which means we are vulnerable to a login phishing attach (https://stackoverflow.com/questions/6412813/do-login-forms-need-tokens-against-csrf-attacks)

But what is the real downside to just storing the auth token in browser storage (i.e. session storage)? XSS becomes slightly more convenient for the attacker? Even with an HTTP-only cookie the attacker can still use the auth token by making requests directly from the site, because if there’s a XSS vulnerability then they don’t need to be able to read the token to use it.

It seems that the popular recommendation just makes things more complicated to protect against CSRF just to make things a little more difficult for the attacker in the case of XSS. Due to the amount of resources making these recommendations I feel like I am missing something and would appreciate any feedback or clarifications!

Here is a couple of sources I’ve been reading that have been quite adamant against browser storage for auth tokens:

  • https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html
  • https://jwt.io/introduction/
  • https://auth0.com/docs/security/store-tokens

Do httpOnly cookies completely prevent XSS attack? [duplicate]

This question already has an answer here:

  • Does setting httponly prevent stealing a session using XSS? 5 answers

I just tried 2 large websites.

At first, I copied all the cookies and wrote them to the incognito tab with some javascript code. I did not pass the authentication because I did not see any private user information. Then I made another trial, I used the Edit this Cookie extension and unchecked all the httpOnly cookies and wrote them to the incognito tab again. And then I got to see everything being who I was.

As far as I know, there’s no way to get httpOnly cookies by javascript.

So does that mean, simply setting the authenticated cookie with httpOnly flag, XSS can then be completely prevented?

Delete cookie or set httponly and secure

I’m currently in the middle of a vulnerability assessment and have found the cookies do not have Secure or HttpOnly set. I have recommended they set both of these to true for their cookies, but the developers have replied with they are not going to, for the following reasons:

  • They won’t be able to delete the cookie when logging out via javascript
  • The cookie is only used for meta data, not to authenticate data requests

Is this a valid defense? I can’t find any (security related) reasons for choosing to delete a cookie over setting Secure and HttpOnly.

Получить httponly cookie без домена

Господа, недавно отвечал на вопрос и столкнулся с интересной особенностью.

Задача, получить Cookie с сайта после успешной отправки запроса.
Запрос отправляю следующим способом:

public async Task<string> Login(string login, string password) {     string data;     var baseAddress = new Uri("https://rabota.by");      var content = new FormUrlEncodedContent(new[]     {         new KeyValuePair<string, string>("login[login]", login),         new KeyValuePair<string, string>("login[password]", password),         new KeyValuePair<string, string>("login[type]", "cad5afb6ed280bc4041d5689d561144a")     });      var cookieContainer = new CookieContainer();     cookieContainer.Add(baseAddress, new Cookie("*0", "*0"));      using (var handler = new HttpClientHandler { CookieContainer = cookieContainer })     using (var client = new HttpClient(handler) { BaseAddress = baseAddress })     {         handler.UseCookies = true;         client.DefaultRequestHeaders.Referrer= baseAddress;          var result = await client.PostAsync("/login/", content);         var cookies = cookieContainer.GetCookies(baseAddress).Cast<Cookie>();         data = await result.Content.ReadAsStringAsync();     }      return data; } 

В результате в var cookies получаю не все “печеньки”.
Запрос успешно отрабатывает, по HTML видны персональные данные, отлавливая ответ вижу, что Cookie успешно задаются, да вот только не отображаются в программе.

Set-Cookie: sessionRabota=4bq9aotr9a24897m8hk1jfo2k0; path=/ Set-Cookie: *0=%2A0; expires=Thu, 13-Dec-2018 00:30:11 GMT; Max-Age=-864000; path=/; domain=rabota.by Set-Cookie: 666c9aea5601eb9d84c330a4f62012b8=7df1b7318a6c5c24327b8982be0b068b; expires=Fri, 23-Nov-2018 00:30:11 GMT; Max-Age=-2592000; path=/; httponly Set-Cookie: d2c3f55b2a337c2bb0aa839194555558=62e5e4a2f71aeee4ca99a69a13496a71; expires=Fri, 23-Nov-2018 00:30:11 GMT; Max-Age=-2592000; path=/; httponly 

Видим следующее:

  • sessionRabota – устанавливается, без особых атрибутов. Она успешно ловится программой.
  • *0 – должна удалиться. В программе по прежнему есть.
  • не понятное название(х2) – вот эти две Cookie видим пометку httponly, остальных отличий я не вижу. В программе, что бы я не делал – они не как не отображаются.

Вопрос: Как их получить программно?