How secure is JWT - token

I know this question is not anything new, possibly already been discuss all over the internet.
I'm new to it but after some study, I agree that it is safe as anonymous could sniff the Token but unable to append anything on it. I'm planning to store JWT in HTML5Storage, and decode the payload for some in-sensitive information: DisplayName, email_address, and role_info and etc.
Here is my question, could anonymous sniff my JWT Token and act on-behalf of me?
If that is possible, how can I avoid that?

In short, JWT by itself is not safe it's just clear text. JWT in basic terms is a standard protocol for how information is defined otherwise known as claims passed between to parties. In combination with JWS (signature) and JWE (encyption) will make it secure. The over arching topic for this is JOSE - Javascript Object Signing and Encryption. Aside from reading the RFC themselves which you should refer to as well there are ton of information online without stating the obvious nor insulting your search abilities. Check out http://jose.readthedocs.io/en/latest/ (includes reference links to RFCs)
So to answer your question if signed and encrypted with industry secure standards in flight (over the wire) and at rest (ie: database) yes it's secure.
In terms of spoofing as you need to pre-cautions in areas of session jacking and/or token jacking and prevention against things like rainbow tables.
JOSE really is just a standard no matter what standard, what you are really asking is about best practices for security measures, you should refer to OWASP as well https://www.owasp.org/
Does that help clarify your question?

Related

How to validate Google OAuth JWT

I'm trying to validate a google jwt I got from the client, but most of the information I can find online is lacking.
For instance, this post on Stack Overflow:
From
https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken
the recommended approach:
"we recommend that you retrieve Google’s public keys from
https://www.googleapis.com/oauth2/v1/certs and perform the validation
locally.
Since Google changes its public keys only infrequently (on the order
of once per day), you can cache them and, in the vast majority of
cases, perform local validation much more efficiently than by using
the TokenInfo endpoint. This requires retrieving and parsing
certificates, and making the appropriate crypto calls to check the
signature. Fortunately, there are well-debugged libraries available in
a wide variety of languages to accomplish this."
It isn't clear to me what I'm supposed to do to validate this jwt. Most of the information I can find about how to verify the signature says to use the x5c key from jwks, but Google's page, found through the discovery doc, excludes that key.
Validation of JWT is covered in the spec (RFC 7519, section 7.2). One of the steps is validation of a signature, it's covered in JSON Web Signature (JWS) spec (RFC 7515, section 5.2). Specifications are the law but to apply the law you should understand how most applications do it or should do it. That is covered in JWT - Best Current Practices (JWT BCP; draft 06)
You can read all of that and try to implement it on your own or you can use one of the client libraries Google provides for you where all of this is, well, also done for you.

Rails security concerns with Authorization token in header for API

I'm building an API and I want every request to contain a token. I found a pretty simple way to do this, but I am wondering if I'm missing any security implications.
The way I'm currently doing it is using authenticate_or_request_with_http_token. I use that to check the token within the header combined with the user's email within a request. If both are legitimate -- then go through with the request.
I am also enforcing https on every request. Is this enough for a secure app? If somebody intercepts the request they can just take the params and the headers and make requests on behalf of a user, but I figured that ssl should encode everything properly. Am I completely misunderstanding ssl as well as the rest of the way I built it?
I think you are basically right.
But the most secure way to do API auth is with something like hmac, where the token is actually generated specific to the specific request and the time, so even if someone does see the URL, they still can't even use it to replay the same API request, let alone make other requests.
http://rc3.org/2011/12/02/using-hmac-to-authenticate-web-service-requests/
For instance, Amazon uses an HMAC-based approach to their API's.
But I think your analysis is correct that in general, if you enforce https, nobody ought to be able to see the pass token clients include in the request. I can't explain why people use HMAC instead; maybe just because there are so so many things that can go wrong and lead to someone seeing the token even in request headers. Including several kinds of man-in-the-middle attacks which ought not to be possible, but if a slip-up somewhere else makes one possible, the HMAC-based approach will still, for instance, prevent a man-in-the-middle from modifying the request the client meant to send, before it reaches the server.
There is HMAC built into the ruby stdlib. Digest::HMAC in the stdlib tells you to use OpenSSL::HMAC instead, but OpenSSL::HMAC contains no docs at all, and Digest::HMAC at least includes some bare bones examples docs. It would be nice to have better docs, but together with the overview of HMAC linked above, you can probably figure out how to use the stdlib ruby hmac to implement your auth pretty easily. It does put a higher burden on the client though, to find an HMAC library in the language of their choice, and implement the hmac auth to your app's specifications (there are a couple choices in how you might incorporate hmac into actual auth flow).

Are session, stored in cookies, safe enough to store important information like id of user?

I'm doing simple authentication. When the user had login, app stored user's id in session[:user_id]. I heard about sessions' encryption, but is it okay? I mean, can user change :user_id in his session to admin's id, for example?
The short answer is no, it's not a good idea.
Especially if people are accessing your site from a public location, or even worse, a public computer. The reason it's 'no' is because of Session Hijacking. You can read about Session Hijacking in section 2.3 of the Ruby on Rails security guide. You can get around this somewhat by using https (TLS/SSL). Refer to the guide for more information.
You could use OAuth or OpenID.
These options might be too hard and too long winded for your purpose.
There is a shortcut; to use an already existing well-known authentication and authorization framework like "Sign in With Google", which is essentially OAuth2 but you can use the tokens to give users with a google account access to your system. Here is the Ruby quick start guide.
Regarding encrypting session data, while a nice idea, it's still open for attack unfortunately. Definitely better than just storing id's in the sesssion data. Over at Information Security StackExchange you'll find some good commentary.
Do you need to encrypt session data?
...
... You don't need to encrypt it. At most, encryption is a form of
obfuscation. You're putting the key on the same system as the data, so
it can always be found and extracted.
ref: https://security.stackexchange.com/questions/18880/do-you-need-to-encrypt-session-data

Is oauth2 insecure?

I am implementing an oauth2 solution for an API i've created and i'm struggling with the potential insecurites (or my understanding at least).
Is it correct that only a single token is generated and used as authentication credentials for an endpoint request. What's stopping a potential brute force attack where an attacker simply submits tokens to the API in the hope that one will be valid and in use?
I've probably misunderstood something but i can't get for the life in me what it is.
Tokens should be difficult to imagine of course. They should not be simple sequential integers for example. There is also no limit on the token length. There are basically two options:
1) build a long token encrypted using your own key (note: it does not have to be long, but it will since cryptography will make it long implicitly). You can check on return the token is really yours because you're the only one that can encrypt and decrypt these tokens.
2) build tokens that are also stored in your database, and are reasonably difficult to create, so you will check the tokens exists in your database.
You can also mix the two approaches. You should also add some expiration time to the tokens (either embedded in it in the 1st case, or aside the token in the database in the 2nd case).
One of the most vulnerable grant types in OAuth 2.0 for Brute Force Attack is Resource Owner Password Credentials type. In such a case, hacker has access to client credentials (clientId and password) and he/she only requires resource owner (user) credentials (username and password).
There is an authentication implementation model described in Java - Spring Security here that would shed some light to avoid this issue.

How to encrypt a password traveling across TCP?

In my game app, running from iPhone/iPad to a central server that I control via TCP, I need to send login information.
What I currently do is send a LOGIN opcode with ascii bytes for login and password in the clear. I don't want to send user's passwords in the clear - they could be on a wifi connection for example.
How can I handle encryption of this? Here are my requirements:
I don't want to use a 3rd party lib, I will if absolutely necessary. If necessary it has to be BSD license or similar
What's the impact of me answering "yes" on "does your App have cryptography in it" to the App store
I want this app to be available in every country
Is it acceptable to, locally on the device, hash the password, and send that cached value only? The user's account could be compromised by the hash being stolen, but the password wouldn't be lost (and I wouldn't be storing their passwords)..
I can't have some kind of OAuth out-of-the-app setup system done as I've experienced before, it's too invasive
I'm sort of at a loss here. I appreciate any good help here as this is one of the last 3 things I need to address before ending almost a year of development.. (so this isn't theoretical or premature optimizing! it has grown in to an actual issue..)
First, the obligatory: "Don't invent your own password scheme. If you aren't an expert, you will do it wrong. If you are an expert, you will do it wrong in a creative way that is horribly broken but which brokenness will be invisible until your scheme is in use by thousands"
Next, be clear about what you want to protect, and why. You mention plaintext user passwords being bad for some reason. Are you concerned that a password the user uses in a bunch of places will be leaked by your application, compromising the user's other accounts, or are you more concerned that the attacker will be able to gain access to your user's account?
My concern with what I read in the subtext of your hashing idea is that the hash that the client sends will never change (unless the password changes). This makes it a plaintext-equivalent for authentication (the attacker need only steal the hash; they can then authenticate without knowing the password). It also makes the password a little more vulnerable to brute-force attacks by someone who can see the hash.
I get the impression that you want to avoid encryption for concerns that it will limit the availability of your application. I can understand that reason.
Let's assume that a cryptographically secure hash isn't cryptography (and I don't know if it is or not, but it isn't in terms of U.S. export restrictions as far as I have read). My suggestion would be a very simple challenge-response protocol to use to verify that the user has the password (I recommend you look up "challenge-response protocol" online).
One caveat here is that I don't address getting the password to the server in the first place; just the server verifying that the user has the correct password for the account. Think of this as a general idea of how you might prevent things like replay attacks, and make life more difficult for attackers that can see the data stream:
Client: "I wish to authenticate as John Smith"
Server: "Okay 'John Smith'-claiming-person, take the current date and time (2011-09-09#12:04:33AM) and a random number I just thought up: 4bazillion, and hash them with your password. Let me know what you got."
Client:
prompts user for password
hashes
Says: "I got: gaAGRtcq4qt22332."
Server:
takes date and time and random number and hashes with password
compares data from client with calculated data
If there is a match:
Says: "Okay, you're in."
Otherwise:
Says: "Go pound sand."
TLS/SSL. Just use it. It is built into iOS.
As for encryption, yes, you will need to claim you use encryption, which will require you to get an (easy) online registration certificate from the government.
Authenticate with your service over HTTPs. You will not need to use any third party libraries. You can implement this as either a post or a get.

Resources