How to set HttpOnly flag and still be able to access the app? - cookies

I have in my app token that on login is saved in cookies and then is used on whole site, if i will remove this token from cookies the app will logout me. Now i need to set on this token in cookies HttpOnly flag but problem is when I set this in frontend react, in can not allow me to login on app because HttpOnly flag don't allow to set in cookes the value. How can i add httpOnly flag and have acces to login to my app i use nest js on backend and react on frontend. Some ideas ?
I tryed to set in backend like Set-Cookies but I need then to save this token in localstorage and it is not a good idea

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.

How to implement token authentication using httponly cookie in Django and Drf

I'm building an application with django , Drf and currently using vanilla JS as Frontend for now.
I searched almost all through web on different use case for authentication on the web and I found out different links but these links seem to always favour the session authentication and token authentication.
Using Django helps us with the session authentication as default so I decided to study the auth process using a token auth.
While doing this, I initially used the localstorage as a store for my tokens gotten from the backend response after user authenticates, But for some reasons which are valid , most devs/engineers advise against using the localstorage as it prones one to xss attacks..
So I decided to implement the httponly cookie method, but I haven't seen a practical use of this done on Django, I've seen theories on implementing all these but haven't seen someone done this..
Please how can I use the httponly cookie with my token stored as a cookie with DJANGO
EDIT
I know a httponly cookie does not allow JavaScript to access a cookie, so I decided to do this.
Django sends the cookie httponly with the token as the cookie
User makes a request to the backend
server gets the token from the cookie sent as a request from the backend.
4)"where the problem now comes" I can't set the token as an header in Django, I tried using the request.headers['Autho...] = Token ....
But that doesn't allow item assignment..
So if my logic is correct this is where I'm stucked
EDIT So this time, I am now able to add a header from the server , using request.META to pass an Authorization key with the Token .... Value, that seems to work fine instead of having to use request.headers for passing an assignment..
But something happened which shocked me, in as much as I'm able to change or add an authorization token from the server , the view still gives me an error, much like I never passed a token at all.....
It's like after the whole efforts and everything nothing still changes, except if it's requested from the client side šŸ˜¢.
Guess I will have to stick with localstorage for now, but still research more or wait for answers .
I've done the Authentication with token using httponly cookie..
I recalled when I asked questions and some loving guys from here helped tho, we couldn't see a straight off answer as we had to research and think as well...
The steps I used was this.
Django takes in user credentials
Django authenticate that credentials
a token is exchanged for that data
we set the token to a cookie using
set_cookie(.... , httponly=True)
** Then it was now time for the real workout .
I created a middleware which will be responsible for setting the token to an Authorization key in header dict.. instead of allowing the client to do this.
---- The client couldn't handle this coz it was now a httponly flag which will prevent js from accessing it as the purpose of using httponly was for this to prevent xss attacks when tokens/cookies are normally stored in a browser storage
we then handle the middleware to our taste, as in mine I tried making sure it work for only some views and not all views (will be planning on making a custom decorator for it)
then last was to šŸ¤”šŸ¤” we'll have fun and smile at seeing me create something as such without a previous tutorial...
The GitHub repo link https://github.com/HarryAustin/tweeter-DrfTest-httonlycookie

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.

Django CSRF protection in Facebook Tab or Canvas App

Django's CSRF protection sets a cookie with the token on response and compares that to the token that is POSTed by the form. It appears in my Facebook Tab app that the csrf cookie is never being set in Safari. I know this has to with Safari's third party cookie policy.
So how are others who are writing Facebook Tab apps or Canvas apps able to set cookies on their app if the user has never visited their domain (which Safari will then allow the setting of the cookie)?