-
-
Notifications
You must be signed in to change notification settings - Fork 215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[discussion] Provide endpoint for refreshing token expiry #156
Comments
for disallowing too fast/many refreshes we could plugin throttling: and make it configurable via knox settings so the user does not need to override the view for it |
The semantic of However we are not really updating a resource via its specific resource URI I like the fact that we don't have to deal with the token Maybe an intermediate solution to cover the above use case and avoid the complexity of exposing all the token resources would be to provide a This is all I have to say about this, I'm just dropping what comes to my mind, you can definitely move ahead with the simple version 🤓 |
Oh and about the throttling part, I agree with @belugame that this should be optin and configurable. It's great to offer a solution that is easy to setup and doesn't require other tooling but I generally prefer to keep this logic at the loadbalancer / proxy level. |
@belugame thats a good suggestion. Would it be a good idea to refactor the @johnraz I think I agree with you said about being able to refresh all tokens at the same time, there is definitely a usecase for that, I will think some more about that. The cool thing about refreshing all tokens at once say are that we dont need to do the expensive hashing on each one, we just need 1 for the initial authentication then its just a matter of a single update statement on the queryset to extend the expiry field. |
@sphrak yes, i like that idea. To make use of the parent-library as much as possible. KISS. |
@belugame I agree with you on that, lets delay the 4.0 release. I am going to hack on this during the weekend so chances are that we have a prototype of this on monday already. But yeah, we might want to break and refactor some more thing before 4.0. |
I'm a bit confused about the |
@johnraz Now that would touch other parts aswell since this setting is used each time a protected endpoint is interacted with to increase the expiry datetime.. hmm I would have to think a bit more about this. But I do think that if we use drf scoped throttling the use of Or am I thinking totally wrong? |
@belugame I am trying to implement a conditional urlpattern setting so that we only expose the refresh endpoint if the user has |
@sphrak : So if you'd want to use DJRF's throttling system to achieve this, this would mean that the eg: If you'd want to make use of DJRF's throttling system to limit the auto-refresh, you'd have to throttle the endpoint itself because auto-refresh happens everytime you authenticate which in turn would block your user from accessing it 3 times per second which would break the endpoint's usage. I hope I'm clear, this is not easy to explain 😄 |
Does this help you? It does not reload it, but you can set custom urls only for the one test method. |
@belugame Yes sorry for wasting your time, I ended up doing that during the weekend but forgot to redact my request for help. |
Can I ask: should we be extending tokens? I've not thought very long and hard about it, but I'm instinctively against the idea (I don't know why yet, I might just be being paranoid) Would it not serve us better for the "Refresh" endpoint to cancel the token that is used for auth, and issue a new token as its response? |
@James1345 this is a very very valid point! Refreshing is indeed better for security than extending. A few points I think of on the top of my head if we go with proper refresh:
|
I also find returning a new token better than extending the old one. That avoids clients having an token infinitely. The longer a client uses the same password, the higher the risk it gets leaked/stolen and the longer an intruder is able to use it. |
Its a good point, but I see a few problems with it and frankly I dont see what problem it solves. But I am in no way a security expert but here are my thoughts on this. Firstly, it should not be a problem extending the lifetime of a token as long as the communication channel is secured over https. So for this to be a problem you first have to defeat https -- in which case it will be game over anyway and it wont matter if you regenerate the token. Second, generating a new token, saving it and deleting the old one is a more costly operation than just simply updating the datetime of the already available token object upon authentication, at any bigger scale at least. Thirdly, an auth token is something I consider mostly the same as a password and normally its not enforced on a user to do a password regeneration on set interval. My point being if extending the token lifetime is a security concern, then so must also the "never expiring" password be. At least in my mind. If we'd opt for a solution where we instead exchange a token for a new token it feels like we have recreated JWT authentication but with extra steps, clunkier and less scalable. Having said that, I am not entirely against this. But again it comes down to https. If thats compromised it doesnt matter what we do -- and to get the token you have to do that or compromise the device on which the token is stored on. So I am having a hard time coming up with a reason to actually justify this. But please, enlighten me if I am missing something. I think its far more likely that a token is leaked by poor "token management" on the client side, at which point I would argue that it is beyond our "responsibility" and even capability -- there is nothing we can do about that, more than doing our part on server-side which is letting unused tokens at least die and also store the token encrypted in the database. For now I am gonna not agree with the statement that regenerating a token is better for security than the reasons I have listed. Again I am not an expert but this does not seem to solve or improve anything. Feel free to tell me im wrong :-) Kindly, |
@johnraz The question for me now is when you think about re-using the login logic... why do we even bother :) the client already has a login logic... and he will get a new token.. so basically he is simply login in again. It is no longer a refresh |
@belugame : You don't want to keep the user/pass in your storage - the all purpose of the token is that it should be shortlived in order to be stored somewhere. So this would mean asking the user his username/pass everytime you refresh, which is impractical and that's why we decided to have auto-refresh IIRC. @sphrak: I'll try to explain clearly my point of view because those topics are always a bit shady 🤓
There are ways a token could be stored or distributed that don't involve TLS where you don't want a token to be long lived.
I definitely agree here.
See my answer to @belugame above and my answer to your first argument.
JWT is a different beast and I think it indeed solves the scalability problem at the cost of complexity.
I again agree here, we can't solve how the client side handles the security but we can do our best to enforce good practice. I think the difference between "extending" and "refreshing" is quite thin... I think it all boils down to this question: "Do we favor performances or good security practices?" This also bring another point I was thinking about regarding performances, we should brainstorm a bit around how to use caching to make things more efficient 😄 I also understand you put a lot of efforts in the current implementation and that changing ways now would mean ditching a lot of what you did but I think it's a learning process and nothing of all that would be lost in the end. Let's keep sharing and find a solution that suits the project well 🎉 |
continuing the follow up discussion in #168
It is indeed the users resposibility to eventually decide on if he or she should upgrade. But my point was not that. Unless we do security backports (and decide on EOL) on major versions its not up to the user, its up to the good will of the developers choosing to allow them to do that. Which wont be the case if we break default behaivor.
I agree here but they still manage to keep breakage at the minimum while still Being opinionated is not a bad thing as long as its clear what is "good". To decide its 'good' merely due to it being technically more secure does not make it good practice. Let me illustrate what I mean with 'technically more secure', I open a https connection, and inside that I open another https connection -- by that logic this is now good practice, because it does indeed make it more secure, but is it solving any problems? Please show me a usecase where extending the lifetime of a token is a 'bad practice' (over TLS) or does 'opening the door to bad practice'. The only usecase yet provided is the email one, where TLS mostly is not involved.
You make it sound as if we cannot have a balance between good performance and good security practices. |
Hey :-) About EOL, backports etc: AFAIK we never had to issue a security fix, so until the situation is "real" I don't believe we should consider this.
I strongly believe we won't get any better than that with a free and without sponsor project like this one. About whether or not the refresh makes sense: Let's say you have a routine running on a server that talks to your API. With a long-lived token or even worse a never expiring token that extends itself, if the one person who got access to the token goes rogue and wants to hurt you or if your secret vault gets compromised the token will be usable and valid With a refresh procedure and a short-lived token, as soon as the token expires, the initial "visible" token will be invalidated and the security breach ends there. You can basically leave it up to machines to deal with the tokens and nobody will ever get access to it unless they get access to the machine and scan the memory but at that stage, the problem lies somewhere else.
I was only saying that in regard to what you said about performance as it's the only valid point I see against refreshing the token. So definitely yes, I think we can achieve a balance between performance and security by actually refreshing the token. I actually addressed that above when I talked about caching. So that's it for the technical bikeshedding. Potential solutions and options:
My opinion on those:
About my general feeling Either way, I feel that the discussion is getting tenser and I don't feel good about it. Let's try to keep it fun and dandy |
@johnraz you are right, it does feel a bit tense and that is not fun. We are sort of drifting away from the actual objective here. Props to you for being the bigger person and bringing it up, thank you for that 😺 .. and I apologize if I in anyway offended you or made you feel uneasey about this. That was not my intension at all, and again my apologies.
I will stress this again -- my main and absolute main issue with this proposal is the performance hit vs the security "gained" given the current usecases given does not justify the implementation to me in its current proposal (ie being the default). I dont have any special interest in "opposing" this change other than the aforementioned reason. However, given those 3 options -- I agree option 3 is probably the best one, but also the hardest. If I can elaborate a bit on what I have in mind for that its this:
In other words I'd say we drop #158 but we keep the auto_refresh functionality as it currently stands. Then we let the actual new "refresh endpoint" have the token exchange functionality and the two functions are mutually exclusive so that only one or none can be enabled at any given time. edit: just to clarify, have the refresh endpoint have two modes -- once that just extends and one that returns a new token? Would that be a good compromise? |
@sphrak thanks for the openness and understanding The solution I have in mind if we want to keep auto expiry extension: We clearly dissociate the 2 concepts in the documentation:
We also make it clear in the doc what's the drawback of each:
We rename The The refresh endpoint should only allow doing a "refresh", not an "extend". So calling it would return a new token and its expiry, a bit of the same way the login endpoint behaves. We could also have another endpoint to fetch information about the token, namely its expiry. Another option would be to ditch |
@johnraz I have been swamped with other work lately and will be for a couple more months. If you dont have anything more in particular to add design-wise I'd say work could be started on this. But again, I will not be able to author it currently, but I could squeeze in a few reviews here and there if needed or just someone to rubberduck against 😸 |
As discussed in #131 @johnraz suggested that we also provide an endpoint for refreshing or increasing the expiration date by simply hitting the new endpoint and the tokens expiration date is increased.
I am thinking that we provide a new url
/refresh/
that just requires an authenticatedPATCH
request to the endpoint which returns the new expiry for the token:{"expiry": "2019-01-11T07:54:34.504745"}
There should also be some control over how often this can happen. Not sure what to do here though.
I am willing to take this on me, but I would like to hear what you think before I start :)
The text was updated successfully, but these errors were encountered: