Session authentication for both browser and non-browser clients - http

I would like to know if the following design for token-based authentication is sound.
Client posts login credential
After validating, server generates (session_key, expires_at) <- (a 256-bit pseudo-random string, some date in the future) and save it in the storage system of choice.
Server sets the session_key in the HTTP-Only cookie in the response.
Server sets the response payload {session_key: ..., expires_at: ...}. The reason is that non-browser clients do not have cookie and they will read this payload, locally store it for the future use.
Concretely, I think the system needs to send the token in the payload as well as a cookie for non-browser clients. Is this a common practice? Or am I missing something important, and there are better alternatives?

As I pointed out in another question, this is fine. It doesn't expose the session key any more than if it is only in a cookie. This could only happen if the attacker can call your authentication endpoint with a valid user/password combo.
Make sure your authentication endpoint does not accept valid sessions and echo back their key as that could expose you to CSRF and session stealing!
For alternative authentication methods, check out the Web Authentication Guide, I put together.

Related

Is Basic Authentication a Session based authentication and why Jwt is more recommended?

I'm learning about Basic Authentication and Jwt Authentication with Java and Spring and I want to ask you if basic authentication is a session based authentication?
I know that in a session based authentication, when the client log in, a sessionId is stored in cookie on the client browser and after that when the client make another request, the server compares the sessionId with the data stored in the memory of the server. And also I want to ask you how is the sessionId sent from client browser to server? Is it sent in the header like a token or how?
And the last question is how the server validate the Jwt token? I know that in case of session authentication, the sessionId sent from client is compared with the data from the memory of the server. But what's happen in case of Jwt authentication? The token is sent with the header and I know that the server validate it and there is no data in the memory of the server. Then how the server compares the token? Any feedback will be apreciated! Thank you!
if basic authentication is a session based authentication?
I know that in a session based authentication
well then why do you ask?
Actually - basic authentication means, that the user credentials(username and password) are sent in the Authorization http header
Authorization: Basic base64(username:password)
The server may or may not use a session cookie. Session cookie may be used with other authentication means or even without any authentication
how is the sessionId sent from client browser to server?
As a session cookie A session cookie is sent as an http header which browser treats as session-persistent
And the last question is how the server validate the Jwt token?
The JWT token should be signed. Note the token has usually 3 parts
header.body.signature
the header specifies a signature type (an asymmetric key or shared secret) and the signature is authenticated (signed or hmac-ed) header and content.
So - the server must validate the issuer, expiration and the signature.
So the server (service provider) doesn't need know the client's identity upfront. The service provider needs to know the issuer's (authentication service which issues the jwt token) public key or shared secret key.
After the jwt validation the service can assume the caller's identity based on the information in the jwt token.
why Jwt is more recommended?
It depends in the use case. (everything has its pros and cons)
I'd recommend using jwt in a distributed and/or microservice architecture. The service doesn't need to access the credentials or to authenticate the user.
In the basic authentication we need to send the username and password for every request.
In the session authentication we will send username and password at initial request. Then from server response we get the session id which stores in browser and gonna use that for requests.
In the token authentication we will send username and password at initial request. Then from server response we get the token and gonna use that for requests.
hope u got it!!

Is the cookie dependent on the browser?

I'm a little confused about the cookie and I want to know can we use cookies somewhere other than the browser, like a mobile app or desktop app. Is the cookie dependent on the browser?
No, cookie is not dependent on browser.
Cookie is dependent on HTTP "User-Agent" -- the software/library client that is acting on behalf of a user, following HTTP protocol. Browser is just one type of it. Other types of "User-Agent" includes:
CLI software that can send HTTP request, such as curl or wget.
Library that can be imported in project and send HTTP request. Take Node.js project for example, they can be request or axios. All major programming language have its own HTTP client libraries.
Self-implemented HTTP client logic code.
more...
In a mobile app or desktop app, if HTTP is used for application, it is highly likely that cookie is used.
Any HTTP client can use cookies. A cookie is just a HTTP header sent by the server, with a value that is sent back to the server by the client in subsequent requests. Consult the documentation of your HTTP client to see if there is built-in support for remembering cookies.
Session Based Authentication
In the session based authentication, the server will create a session for the user after the user logs in. The session id is then stored on a cookie on the user’s browser. While the user stays logged in, the cookie would be sent along with every subsequent request. The server can then compare the session id stored on the cookie against the session information stored in the memory to verify user’s identity and sends response with the corresponding state!
Token Based Authentication
Many web applications use JSON Web Token (JWT) instead of sessions for authentication. In the token based application, the server creates JWT with a secret and sends the JWT to the client. The client stores the JWT (usually in local storage) and includes JWT in the header with every request. The server would then validate the JWT with every request from the client and sends response.
The biggest difference here is that the user’s state is not stored on the server, as the state is stored inside the token on the client side instead. Most of the modern web applications use JWT for authentication for reasons including scalability and mobile device authentication.
Scalability
Session based authentication: Because the sessions are stored in the server’s memory, scaling becomes an issue when there is a huge number of users using the system at once.
Token based authentication: There is no issue with scaling because token is stored on the client side.
Multiple Device
Session based authentication: Cookies normally work on a single domain or subdomains and they are normally disabled by browser if they work cross-domain (3rd party cookies). It poses issues when APIs are served from a different domain to mobile and web devices.
Token based authentication: There is no issue with cookies as the JWT is included in the request header.
Token Based Authentication: using JWT is the more recommended method in modern web apps. One drawback with JWT is that the size of JWT is much bigger comparing with the session id stored in cookie because JWT contains more user information. Care must be taken to ensure only the necessary information is included in JWT and sensitive information should be omitted to prevent XSS security attacks.

How is JSON Web Token more secure than cookie/session?

How is using a JSON Web Token more secure than an opaque session token, In both the scenarios the tokens are first sent to the client and then verified on the server when a client requests a protected resource.
There are several reasons people say JWTs are more secure. I’ll list them and also give you reasons why that might not really be the case as it swings both ways.
JWTs can be signed using a secret with secure algorithms like HS256 and RS256. A comprehensive list can be found here. On top of that, you can also encrypt the payload of the JSON Web token. However, session tokens can also be generated securely with a top-notch algorithm and stored in a signed cookie.
JWT can either be stored in a cookie or Web Storage( local/session Storage ). If you are not storing your JWTs in a cookie, then you are not vulnerable to CSRF. And you can decide to send them through the Authorization header for every HTTP request. However, there is still a caveat. Javascript is used to access the JWT from the Web storage, which still leaves you open to other forms of attack such as XSS (Cross-Site Scripting). Worthy of mention is that it is easier to deal with XSS than CSRF.
In a situation where your JWT has been tampered with, you can revoke or blacklist the token. This involves making a call to the DB every time you want to perform this kind of operation which I won’t advise you to do. The preferred option is to use short-lived tokens.
In the case of OAuth, opaque tokens otherwise known as bearer tokens are random strings that will be stored in some kind of hashed storage on the server together with an expiration, the scope requested (e.g. access to friend list) and the user who gave consent. Later, when the API is called, this token is sent and the server lookup on the hash-table, rehydrating the context to make the authorization decision (did it expire? does this token have the right scope associated with the API that wants to be accessed?). The main difference between opaque tokens and signed tokens(e.g JWT) is that JWTs are stateless. They don’t need to be stored on a hash-table.
Conclusion
The libraries used to sign and encrypt your JWTs should be secure to ensure your authentication process is also secure. You should also use cookies as storage mechanism rather than using them for login. You can argue that there are more benefits to using JWTs like they are easier to scale and they can be used in OAuth cases which you can find in this article. At the end of the day, In my opinion it simply falls on the developers’ reasoning/logic to ensure the right steps are followed to make an app secured regardless of what form of token is used for authentication or authorization. Use case is also key in this context!

RESTful best practice for authentication

and thank all of you for viewing this question.
I am not sure to on how do this so i am asking for the community help on this matter.
I read int his post Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant" that sessions are not "completely" advised on the REST convention, and that all authentication should be made using HTTP Basic authentication or Digest.
Ok, so far i get it.
But has far has i know, basic authentication is made on the actual server against a regular non-encrypted text file.
Would it be going against the convention, putting the username/password in the http request parameters, instead of passing them down trough the headers and letting the web server do the authentication?
This way, for every request made, the user/pass parameters would be checked and managed using my own logic. I mean using a database table, that has all the info necessary for the application.
The method I currently use is the first request is for a auth token via a POST method, which contains Headers of Username and Password, these are then verified against my authentication methods. If the credentials are valid, I return a time limited token. All subsequent requests must have the auth token as a header, which is checked and if valid access is allowed. I maintain the list of valid token in code and expire them as required. This is faster than having to validate the username & password on each call and is slightly safer than the username & password being passed in with each call as a token could be stolen, but it is only valid for a small period of time.
All of this this must be run under SSL otherwise the data is not secure and users credentials can be read.
Basic auth is handled by the server however the server chooses to handle it. There certainly doesn't have to be a plaintext file containing usernames and passwords! My current client stores passwords in a 1-way salted hash in their database. On an incoming request, the plaintext password is pulled from the header, salted, hashed, and them compared to the database value.
Putting a password in a request parameter is a really bad idea. What happens when a user copies and pastes a URL to email to their coworker?

How to secure an API

I am developing an API as a middleman between a Windows app and the database. The webserver will just be an ASP. NET generic handler returning json.
Users will log into the app and their credentials will be transmitted over the wire. From there what I was going to do was generate a session key that the app could use from then on with every request.
This will not be an open API in the foreseeable future.
Now what I am wondering is if this is secure enough? How can I stop people from using fiddler to just replicate the calls?
Is there a better approach to this? Would it help if I used SSL?
I don't want to complicate matters by using oauth.
Thanks!
Use SSL. In order to obtain the session token the client should authenticate himself with a username and password transmitted over SSL. Once authenticated the token should be transmitted to the server over SSL to prevent from man-in-the-middle attacks.
So here's the flow:
The client sends his credentials (username and password) over SSL to a web method
The web method verifies the credentials and generates a session token and returns this session token to the client.
The client sends the session token on subsequent requests to protected resources.
The server verifies the token and if valid grants access to the protected resource.
You use simple Forms Authentication to generate the session tokens. The FormsAuthentication.Encrypt and FormsAuthentication.Decrypt methods could be a good start for you. The forms authentication token contains an encrypted value of the currently authenticated user. If you are running in a web-farm make sure that you have static machine keys on all nodes of your web farm, otherwise a session token encrypted on one node might not be decrypted on another node.
As an alternative to session tokens you could use basic authentication over SSL. The drawback is that credentials are sent over the wire on each request. Even if you are using SSL, the password is still transmitted over the wire, so this method is less secure than session tokens but easier to setup.

Resources