How Do You Secure API Using JWT To Prevent Fake Websites - api

I understand JWT can be used to authenticate a user but not much info seems to available on how you can secure the connection between frontend and backend api to ensure the website is not a fake duplicated used to lure users and steal their creds.
Maybe I'm just not wording my searches properly or understanding the topic, but how would you ensure that the client trying to connect to your API backend is authorized to and denied if it's not, even if the correct creds are used? This is for JWT.
I know it can be secured using API keys but this question is specific to JWT.

There isn't a great deal you can do against social engineering attacks. If data is sensitive then giving users regular warnings about how people might try to trick them with fake websites is fairly common.
Wikipedia lists a number of techniques that can be used to customise the UI to make it easier for the user to recognise that they are on the right site.
2 factor authentication can also help. While incorrect credentials could result in a token being passed to the attacker (allowing them access to the site), it will expire after whatever time limit you put on it and they will need to refresh it or be unable to reuse the password (since they won't have the new 2FA code).
You can also monitor for logins from large numbers of different users from the same IP address.

Related

Securely using JSON web tokens to programmatically authenticate a user from one system into another

My team and I have been working on a web application for our clients that uses JSON web tokens for authentication and authorization. Using Azure AD as our identity provider, we verify a user's identity and generate a signed JWT with the user's permissions in it. The JWT then gets included in the authorization header of all subsequent requests to the APIs. Pretty standard stuff as far as JWTs go.
We're now being asked to provide the capability to link directly into our system from another third-party web application without forcing the user to reauthenticate. I'm trying to figure out if there's a way to do so without creating a massive security loophole.
The way I picture this working would be to implement an endpoint for programmatic authentication in our system that accepts a cryptographically signed payload with an API key and the user's ID or email address. The third-party system would have a private key with which to sign the payload, and we'd have a public one to verify the signature. If the request is legitimate, we'd issue a token for the specified user, and they could use that to link to whatever they like.
I'm already getting yelled at by at least one person that this is a complete joke from a security standpoint because, among other things, it completely bypasses AAD authentication. I believe the third-party system in question does use AAD for authentication, but that's not really relevant either way because we're trusting them implicitly whether they've authenticated their users or not. Either way I take his point.
I'm not a security expert and I don't claim to know whether there even is a proper way to do this kind of thing, but from my vantage it doesn't really seem all that much less secure than any other mechanism of authentication and authorization using JWTs. Is that true? Are we nuts for even trying? Is there a way to do it that's more secure? What should I know about this that I demonstrably don't already?
Thanks in advance for the help. At the very least I hope this spurs some helpful conversation.
Single Sign-On (SSO) enables users to enter their credentials once to sign in and establish a session which can be reused across multiple applications without requiring to authenticate again. This provides a seamless experience to the user and reduces the repeated prompts for credentials.
Azure AD provides SSO capabilities to applications by setting a session cookie when the user authenticates the first time. The MSAL.js library allows applications to leverage this in a few ways.
MSAL relies on the session cookie to provide SSO for the user between different applications.
Read more in this documentation.

Is it possible to have a stateless server with token based authentication that is not vulnerable to replay attacks?

Currently I have a server that makes use of JSON Web Tokens in order to manage user authentication.
When a user submits a valid authentication request, they receive a JWT which contains information such as their user ID that allows the server to process authentication sensitive requests.
The plain text body of the JWT will take a form similar to:
{
"UserID":"100",
"Expires":"(expiryDate)",
"IssuedBy":"ServerOne"
}
However, as you could quite correctly point out, this does not afford us any way to validate that the agent presenting the access token is in fact the user who it was originally issued to.
As such, if someone were able to obtain the JWT, then assuming it has not expired they would be able to assume the user's identity and gain unauthorised access.
A stateless server is a must for the current project, so I would struggle to use a solution which involves the server keeping track of logged in users.
Is it possible to achieve security using Tokens in this manner?
I've done a bit of reading on the topic, and I remember someone suggesting to use something like the "X-Forwarded-For" header and placing the user's IP in the token then comparing the two, but that has it's own drawbacks.
There are a couple of specs in the OAuth 2.0 / JWT space right now, which try to address this problem. Take a look at RFC 7800 and this draft.
There are several commercial Authorization Servers / Identity Providers out there which already support RFC 7800 and a couple of open source implementations as well.

What CORS policy to use for iOS and Android apps?

I'm building an API that is meant to be used by iOS/Android apps.
The app uses JSON Web Token to authenticate users.
I ran into CORS issues when trying to talk to the API from the native app.
So I added CORS Headers for ALL Origins (only on urls starting with /api/).
It works fine now, but I'm wondering if what I did is not a potential vulnerability?
Should I allow ALL origins? If the API is going to be requested by native apps, is there a way I can know the Origin host in advance?
I'm quite confused.
Thanks in advance for your help.
The user shouldn't need CORS protection if they have the token. The token is fully identical to the user logging in with their user name and password each and every time you send the token to the server. The threat model that CORS is protecting against is a malicious domain/site, other than your own site, doing an AJAX request to your server using the cookies (including session id) for your domain.
If a malicious domain or entity has your user's token, your user's identity is so PWN'd, that it doesn't really matter what sort of CORS protection you try to do. The malicious domain has the equivalent of your user's username and password. They are completely compromised, until you invalidate their token.
Thus, don't worry about where a request is coming from ( CORS ), when the malicious entity has completely compromised the user's account. Just protect the token as if it were the Queen's jewels. Send it over SSL and store it securely. If the malicious entity gets the keys to Fort Knox, you have bigger problems than where the request is coming from.
Don't Be afraid of let the Cors Origin : * because if you limit server access you may put your business in bad unstable situation so work hard on tokens.
But in my manner I research net and found any encryption have an decryption sometimes as a third party tool and say wow.
Finally Make my own Encryption in 20 days and each day make it harder to decrypt.
Final Answer : understand encryption & decryption then make your functions the way you want and everyone doesn't know.
Don't waste your time for SSL or Internation HASH Algorithms if you want Maximum Security. Afterward you can mix your encryption with International hash algorithms as you like.
Begin from easy character encoding then update and update more , one time you did it you can use in every app you make.
Hope to be helpful.

Token authentication with rest backend secure enough

I would like to secure my mobile app ( hybrid app, build with ionic framework). On backend site I use the play framework. I would implement the following case. The user of the app should authenticate to rest backend by email and password, if the credentials correct the backend generates an token return ok with the generate token to client, otherwise the backend return bad request. If the user would try to login with incorrect credentials more then 10 times the user would deactivated for 1 hour.
The mobile app would load json data from backend with ajax calls, on each call in header would set the field 'X-AUTH-TOKEN' and the generate token. The backend check the token and if the token is correct the client get data from server with status ok else the client get none data and the status unauthorized. If the user logged out the token would destroyed on server and client side. The token would not change as long as the user is logged in, in worst case the token would not changed over more than many days. I could implement, that on each call the date of last call can saved and if the last call is more than x days in past the server return unauthorized and destroy the token. So the user should logged in. Is the case secure enough, or should I implement more logic?
What you are describing is very similar, if not identical to the many, many implementations of OAuth2. For more information on these types of flows, including diagrams, check out how Google describes their OAuth2 processes here: https://developers.google.com/accounts/docs/OAuth2
I'm not familiar with the play framework but you should speak with framework experts to see if there is a well-tested, battle-hardened oauth2 implementation out there for the Play Framework. If so, you want to use that. You really don't want to (and shouldn't) roll your own implementation unless you know what you're doing and are willing to pay for people to pentest it. Really, please don't do this if unsure.
On the Ionic Framework / Angular / Cordova side, you've basically got it correct, but should always consider some basic security considerations:
My guess is that you'd use local storage to store the access token. In REST we don't have sessions like in a traditional web server scenario so we use the token in lieu of the session. Of course the downside is that local storage can easily be inspected to obtain the access key if someone had either root access on the device and was able to work their way into the app sandbox and knew exactly what api key to grab from local storage, but if someone has root or physical access to the device then you've got a bigger problem, so this isn't a design flaw per-say. To a certain extent, using this method you're relying upon the OS/browser's local storage sandbox to prevent other apps from accessing the local storage in your ionic app. This is a bet I would be willing to make, but you'll need to judge that based on your security vs usability needs.
What you should really be focusing on is protecting the token from people who may be listening on the wire (think coffee shop wifi). This means setting up your auth rest servers to use exclusively HTTPS (don't fail back to HTTP). This may have downsides, but will be worth it to protect your user's data. You also correctly identified using the token header. You should never pass auth tokens in anything but the header or POST data.
Generally speaking, what you are describing should be safe for use in a consumer level app. This assumes you don't unwittingly use any malicious third party code in your app. As always, you should be especially wary of third party code and only use code that you absolutely trust. Any code run from inside your app can access local storage in the Cordova/browser local storage sandbox and could theoretically export the api token for use in other software to access your api. With that said, you asked about authentication and not authorization. Keep in mind that your users need to only have access to do certain things in the app based on user-roles or some sort of ACL. This authorization outside the scope of this answer but you need to ensure that this is done on the server side and has rate limiting or soft-deletes for shared resources to prevent a malicious user from deleting everything.
Good luck with ionic and have fun.

Should HTTP Basic Authentication be used for client or user API authentication?

A typical recommendation for securing a REST API is to use HTTP Basic Authentication over SSL. My question is, should HTTP Basic Authentication only be used to authenticate the client (ie. the app accessing the API), or can it also be used to authenticate the user (the consumer of the app)?
It seems most APIs have to deal with both, as almost all web services employ some sort of user accounts. Just consider Twitter or Vimeo—there are public resources, and there are private (user specific) resources.
It seems logical that a simple REST API could do both client and user authentication at the same time using using HTTP Basic Authentication (over SSL).
Is this a good design?
By authenticate the client you probably mean the usage of API Key, this mechanism is used to track the concrete application/client. The second thing is that it gives you the possibility to disable the application by disabling the key, for example when client's author removes his account from the service. If you want to make your API public then it is a good idea.
But you need to remember that it gives you no real protection, everybody can download the client and extract that key.
I would not recommend to use Basic Authentication for API authentication. When it comes to authentication then you should consider that the application (client) developer has to implement its side of the authentication, too. Part of that is not only authentication itself but also how to get credentials and even much more than that.
I recommend to make use of an established authentication standard that ships with client libraries for the most popular programming languages. Those libraries make it much more likely that developers are going to adapt your API, because they reduce implementation effort on the client side.
Another important reason for using authentication standards is that they make developers (and others) more confident in the security of your authentication system. Those standards have been audited by experts and their weaknesses and strengths are well known and documented. It is unlikely that you are going to develop a nearly as solid authentication flow unless you are a security expert :-).
The most established standard in this field is OAuth but you can find alternatives by searching for "oauth alternatives".
How does OAuth help you with your problem setting?
In OAuth 2, the application client has to obtain an access token for a user before accessing any protected resource. To get an access token, the application must authenticate itself with its application credentials. Depending on the use-case (e.g. 3rd party, mobile) this is done in different ways that are defined by the OAuth standard.
An access token should not only represent a user but also which operations may be used on what resources (permissions). A user may grant different permissions to different applications so this information must somehow be linked to the token.
How to achieve such a semantic for access tokens however is not part of OAuth - it just defines the flow of how to obtain access tokens. Therefor, the implementation of the access token semantic is usually application specific.
You can implement such token semantic by storing a link between an access tokens and its permissions in your backend when you create the access token. The permissions may either be stored for every user-application combination or just for every application, depending on how fine-granular you want things to be.
Then, each time that an access token is processed by the API, you fetch this information and check whether the user has sufficient permissions to access the resource and to perform the desired operation.
Another option is to put the permission information into the access token and to sign or encrypt the token. When you receive the access token, you verify or decrypt it and use the permissions that are stored in the access token to make your decision. You may want to have a look on Json Web Tokens (JWT) on how to accomplish that.
The benefit of the later solution is better scalability and less effort during backend implementation. The downside of it are potentially larger requests (especially with RSA encryption) and less control over tokens.