How to give clients JSON web token (JWT) in secure fashion? - python

I have a python application that needs to give users a JSON web token for authentication. The token is built using the PyJWT library (import jwt).
From what I have been reading it seems like an acceptable practice to give the token to a client after they have provided some credentials, such as logging in.
The client then uses that token in the HTTP request header in the Authorization Bearer field which must happen over TLS to ensure the token is not exposed.
The part I do not understand is what if the client exposes that token accidentally? Won't that enable anybody with that token to impersonate them?
What is the most secure way to hand off the token to a client?

You could encrypt the token before handing it off to the client, either using their own public key, or delivering them the key out of band. That secures the delivery, but still does not cover everything.
In short, there's no easy solution. You can perform due diligence and require use of security features, but once the client has decrypted the token, there is still no way to ensure they won't accidentally or otherwise expose it anyway. Good security requires both participants practice good habits.
The nice thing about tokens is you can just give them a preset lifespan, or easily revoke them and generate new ones if you suspect they have been compromised.

Token will be build based on user provided information and what you back-end decided to be part of the token. For higher security you can just widen your token information to some specific data of the user like current ip address or device mac address, this will give you a more secure way of authentication but will restrict user to every time use the same device, as a matter you can send a confirmation email when a new login happens.

Related

Is it a good idea to use JWT as verification token?

I'm going to use FastAPI Users for my application. I saw that it generates JWT tokens to perform verification processes in the application. For example, in order to verify user email address or to request password change. Is it a good idea in terms of security?
JWT is state-less authentication and is so useful if you use backend with multiple frontends (mobile app, website UI and ...)
Its security is also Depends on your implementation.
If you use different secret key than default fast-api tutorial (I saw it on some projects!) and use rational expiration date, its secure enough to handle big projects.
consider you should logout every login sessions of specific user, which is logged-out from one client if you have multiple clients. which means you should implement some kind of black-list JWT.
About verifications, I recommend using two factor verification. I usually use security code send to email or SMS code. It's more secure if you consider this scenario:
A user is logged-in on a device and JWT token is not expired. another user using same device in office and can change password without any second factor security layer. If you have code send to the mobile, its more secure and no one can access it easily!

Python AuthLib Resource Server using a BearerTokenValidator with Multiple Strategies

I have a resource server (built with Flask, but not sure if that matters right now) that has a RESTful API. The API is secured with OAuth2 access tokens and scopes.
Currently the access tokens are opaque (not JWT) and the resource server needs to call the /oauth/token/info endpoint on the auth server to check if the access token is valid and get the list of scopes associated with the access token, and then validate the scopes granted against the ones required. We have some custom code for this.
We now want to start to use JWT access tokens so that we can avoid this call to the auth server, but we can't roll them out to all OAuth clients just yet, only some. So the resource server will be getting a mix of opaque access tokens and JWT access tokens. The JWT will be signed with a RS256 private/public key, and the public key will be available from the auth server at a /oauth/discovery/keys endpoint that the resource servers could hit on startup once and cache so that it doesn't need to hit it on every request, unless the public key changes and doesn't match the kid in the JWT.
While doing this, I was hoping we could get rid of some of the custom code we've written and use some tried and tested library for us, hence AuthLib.
However, I can't seem to find any good examples of how to configure a resource server to handle either of these cases individually, let alone both at the same time. The examples I see seem to assume the resource server has access to the access token database.
I'm assuming I will need to write my own BearerTokenValidator that handles this, but I was hoping there would be examples somewhere on how to go about that. Ideally with the ability to cache the public key for the JWT and only refresh when the JWT kid claim changes.
I was sort of hoping that a TokenInfoBearerTokenValidator and a JWTBearerTokenValidator existed that I could use that did most of the work for me. Maybe there are and I'm just missing it?
AuthLib 1.0 has been released with additional support fro JWTBearerTokens that makes this easier to accomplish now.

Personal Access Tokens, User Tokens

I am writing a basic python script and I am trying to use the Github API. Because I am new to the development scene, I am unsure of what I can share with other developers. Do I generate a new personal access token (that I assume can be revoked) or do I give them Client ID and Client Secret?
Can someone explain how OAuth (Client ID and Client Secret) is different from a personal access keys?
Does this logic work across all APIs (not just on Github's)?
The Short, Simple Answer
You should probably give them none of those things. They are equivalent to handing over your username and password to someone.
The Longer Answer
It depends...
Personal Access Tokens
Your personal access token is a unique token that authorises and represents you during API calls, the same way that logging via the web interface authorises you to perform actions there. So when you call an API function with a personal access token, you are performing that API action as if you yourself had logged in and performed the same action. Therefore, if you were to give someone else your token, they would have the same access to the site as they would have if you gave them you username and password combination.
Personal access tokens have attached scopes. Scopes control exactly how much access to GitHub a particular token has. For example, one token my have access to all private repositories, but another token only to public ones.
Client IDs
A client ID represents your application, rather than you. So when you create an application, GitHub gives you an ID that you use to identify your application to GitHub.
Chiefly this allows someone logging into your application using OAuth to see on the GitHub web interface that it's your particular application requesting access to their account.
Client Secrets
A client secret is a random, unguessable string that is used to provide an extra layer of authentication between your application and GitHub. If you think of the client ID as the username of your application, you can think of the client secret as the password.
Should I Share Them?
Whether you wish to share any of these things depends largely on how much you trust the other developers. If you are all working on the same application, it's likely that you will all know the client ID and client secret. But if you want to develop an open-source application that people will install on their own machines, they should generate their own client ID and secrets for their own instances of the app.
It's unlikely that you should ever share a personal access token, but if you have a bot account used by the whole team, then sharing the tokens could also be okay.

How to register an oauth2 client?

I'm writing an oauth2 provider and am not sure how to implement client registration. The oauth2 specification doesn't cover this aspect:
The means through which the client registers with the authorization server are beyond the scope of this specification but typically involve end-user interaction with an HTML registration form.
Moreover, the oauthlib documentation has the following to say about the Client data model:
It is common practice to link each client with one of your existing users. Whether you do associate clients and users or not, ensure you are able to protect yourself against malicious clients.
Now I sure would love to protect myself against malicious clients, but how can I link a client to a user if registering a user requires a registered client?
The oauth2 spec again has something to say about this, but it's very cryptic:
Client registration does not require a direct interaction between the client and the authorization server. When supported by the authorization server, registration can rely on other means for establishing trust and obtaining the required client properties (e.g., redirection URI, client type). For example, registration can be accomplished using a self-issued or third-party-issued assertion, or by the authorization server performing client discovery using a trusted channel.
Questions
How should a client be registered if linking to a user is required, given that registering a user requires a registered client?
How should a client be registered if linking to a user is not required? What is meant by 'redirection URI, client type, and third-party-issued assertion?
When answering this question, I am going to assume there is already an access control framework that this provider will be attached to, and the application that will use this provider will have HTTP access and has capabilities to handle HTML forms, as no details on this whatsoever were provided by the question (i.e. what framework is this provider going to sit on, or is it something completely naked and standalone on some homebrewed framework).
I'm writing an oauth2 provider and am not sure how to implement client registration. The oauth2 specification doesn't cover this aspect:
The means through which the client registers with the authorization server are beyond the scope of this specification but typically involve end-user interaction with an HTML registration form.
While it doesn't spell it out explicitly, it did suggest that typical registration of a client involves end-user interaction with a form. If you see how others have done it (such as through imgur's API, OAuth 2 user documentation) you will find that it provides a Registration link and hey that's how clients are registered. No OAuth 2 is required as you are already authenticated via the browser.
Now I sure would love to protect myself against malicious clients, but how can I link a client to a user
By linking your server applications's representation of the client details to the user (tracked by some system) that created those client details? It's not like user specific data suddenly becomes more mystical just because it is used for authenticating an OAuth2 client. If you find abuse related to access using those client details (from your logs) you could just revoke those credentials related to that client, and punish the user that own that client. (Unless it's their clients... erm, your other users using that client is doing the abuse but you should be able to see that, right?)
if registering a user requires a registered client?
If you really want to have people register their clients using their client before they register their client, that's pretty much madness (i.e. a chicken and egg problem that shouldn't need to exist). Nowhere in the specification this was ever suggested that they are mutually inclusive problems. Here, to simplify this:
You can use a registered client to register a user
You can register a client to a registered user
Those two things are completely separate from each other. You have to have one before the other (actually, you can create a user registration form that also generates a client credentials at the same time, but I digress), but really, a registered client is essentially reducible to some credentials that are shared between that client and the provider it is registered against.
You can make your own registered clients, too, since you have full control of the provider, you can inject any credentials that will be used by that registered client of yours to do whatever you need, including registering new users, but...
How should a client be registered if linking to a user is required, given that registering a user requires a registered client?
You know you can just register a user using a standard HTML registration form? Just use the user registration form that the framework provided, or write one* if that framework doesn't already provide one.
How should a client be registered if linking to a user is not required?
When I implemented an OAuth1 provider for Plone, client registration can only be done by administrators/managers of the site, so not something user can do, thus someone has to contact the owners of the site to find out how to do it. This generally removes the security problems associated with not linking clients to users (since clients are now linked to actual people coding those clients up who are not necessarily users of the site through external means).
I realized I did not really answer this question, but this is really up to your implementation and what needs/restrictions you decide to limit/provide. I mean you can have a totally anonymous form on your site and let it rip, but I don't think you want that as that weakens security of your application dramatically.
What is meant by 'redirection URI, client type, and third-party-issued assertion?
If you go to the sections as specified in the RFC, you will find answers there:
Redirection URI
There is actually quite a lot of ways to subvert the security of your users' (resource owner's) data if this is not carefully understood, but is used by the authorization server to "redirects the resource owner's user-agent back to the client", as the authorization is done on the authorization server which is part of the provider's infrastructure. So in general, the client has to let the authorization server know where/how it gets back to itself after the resource owner authorizes the client's access through this redirection URI. However, if the redirection URI specified is not verified, security issues can and will happen.
For instance, native applications (a client profile of the client type public) will (used to, I am coming from an OAuth1 background) have the complete client credentials embedded inside the application, which will be extracted by hostile attackers in a bid to masquerade as a legitimate web application (another client profile, but can be considered as a confidential client type) that makes use of your application's services. Once the hostile attackers are up and running they will entice your users (resource owners) to use their masqueraded site, and grant the masqueraded site their access tokens through your authorization server and if redirection URIs are not validated, it will redirect your users (resource owners) to the attacker with the authorization code (as outlined in section 1.3), giving the attacker access to your resource owner's data.
That was the easy common case - another problem case is that your other web application client might have a credential leak without them knowing, resulting in this exact scenario.
Hence this is why they suggest that you should only "redirect the user-agent to the client's redirection endpoint previously established with the authorization server during the client registration process... after completing its interaction with the resource owner", which can mean that only the domain name registered to that client will be legitimate redirection targets, otherwise something went wrong and your authorization server aborts and does not provide the authorization grant.
Client Types
Again, just read/scrutinize all that carefully.
Third-party-issued assertion
As opposed to self-issued client registration done kind of like a client registration form, your application might delegate the client authentication to a third party which will do the verification for you. If you have to worry about this and don't know where to start I suggest you ignore this and just only do self-issued client.
* Are you really sure you want to write an OAuth2 provider without any underlying user/ACL framework for you to hook this to? I mean you can write one but you should really build that part first before you worry about OAuth2 (again, I am not making any assertion, since the question provided no information on this).
Now, if you are not doing this as part of some existing framework but just something standalone that you want to toy/try out as learning, I strongly suggest you to pick something else because this is probably beyond what you can do in a correct manner. Especially if you don't already fully understand the implication of this with regards to the underlying ACL and security of the resource owner's data, and other related stuff.
No offense, but these things are very very difficult to do correctly. Even the bigger companies have had security issues with their OAuth2 solutions.
Finally, speaking from experience, I spent about four (4) weeks (!) staring at the OAuth1 specification years ago, using a poorly written Python OAuth library (later replaced with oauthlib, which is much better) in an attempt to build an OAuth1 provider on top of Plone, before I got a single line of code directly related to the provider committed. A lot of junk/trial code written was thrown away, and this was done because understanding all of this stuff actually took time (granted, I was not exactly working full time on this, had other responsibilities too which was distracting me from this). Another part of the time was spent trying to understand how the user/security stuff is put together at the Zope/Plone layer. Granted I was still relatively new to that side of that framework, but I can guarantee you that this road is not going to be easy... however I did seem to find that OAuth 2 cleaned things up in some ways to make it easier to understand, but find that the security may have been weakened. That said, I currently have no immediate plans to port my Plone addon to support 2.0 as my sponsors does not require that, so there may be things I suggested up there that may differ slightly from 2.0. Would love to hear your comments if others have read this far. I wrote way more words than I originally intended to, oops.
Anyway, good luck on your adventures.
Additionaly for dynamic registration, please go through this spec as well
https://www.rfc-editor.org/rfc/rfc7592

Google App Engine as Authentication Server for Mobile Application

I am attempting to utilize Google App Engine as an Authentication Server for a mobile application that runs on android natively. User names and passwords will be stored in GAE and my goal is to be able to both store and verify credentials from the mobile application using GAE. Is this possible? I've looked into OAuth and JSON, but I don't think I have the proper setup for that.
Also, if I'm going about this the wrong way, please point me to the proper path.
If you are interested in having a more API-like implementation in your GAE instance, I would definitely look more into OAuth. But if you are only interested in validating credentials for this one mobile application then you need not go that far.
Fortunately you can call your GAE instance over SSL, that means that you can offload all the business of handshaking and encryption. Then I would simply use either http-basic authentication, or simply send user-id and encrypted password as parameters in the request.
On the iPhone there is a KeyChain for password storing, maybe there is an Android counterpart? Anyway, make sure to store passwords encrypted on the device and in the GAE-datastore. Send the encrypted password when validating credentials. You should never know your user's clear text passwords. That would provide a level of obscurity which I think is enough (definitely so when sent over SSL).
Then you can simply return whether the account credentials are verified or not.
If by "storign credentials" you mean storing username and password, then I imagine you are going about this the wrong way. Whether you are talking about OAuth or OpenID, the idea is that you never see or have access to the password (and perhaps not username either) of the delegated authentication mechanism. Instead you receive an authentication or authorization token to do your work (and in the case of OpeniD, some meta information about the person like first / last name and e-mail address).
By the way, have you considered a 3rd party, such as Janrain?

Categories

Resources