Session Authentication vs Token Authentication
I am trying to get a handle on some terms and mechanisms and find out how they relate to each other or how they overlap. Authenticating a theoretical web application and mobile application is the focus. The focus is on the exact difference between token based authentication and cookie based authentication and if/how they intersect.
http basic/digest and complex systems like oauth/aws auth do not interest me
I have a few assertions which I would like to put out there and see if they are correct.
- Only using authentication tokens without sessions is possible in mobile applications. In a browser context you need cookies to persist the tokens clientside.
- You exchange your credentials (usually username/pw) for a token wich can be limited in scope and time. But this also means that the token and everything relating to it must be persisted and handled by the server as well.
- Tokens can be revoked serverside. Cookies do not have that option and will/ should expire.
- Using only cookies means that sessionid is related to the user account and not limited in any way.
I am hoping i am not too far off the mark and am thankful for any help!
I'm not sure your understanding with #3 is correct. Web servers/apps can revoke a cookie in the sense that its session value can be disassociated with a user identity. The browser may continue to present it in requests, but the server will not honor it as proof of identity. If I misunderstood your meaning, can you please clarify?
In Session-based Authentication the Server does all the heavy lifting server-side. Broadly speaking a client authenticates with its credentials and receives a
session_id(which can be stored in a cookie) and attaches this to every subsequent outgoing request. So this could be considered a "token" as it is the equivalent of a set of credentials. There is however nothing fancy about this
session_idstring. It is just an identifier and the server does everything else. It is stateful. It associates the identifier with a user account (e.g. in memory or in a database). It can restrict or limit this session to certain operations or a certain time period and can invalidate it if there are security concerns. More importantly it can do and change all of this on the fly. Furthermore it can log the user's every move on the website(s). Possible disadvantages are bad scale-ability (especially over more than one server farm) and extensive memory usage.
In Token-based Authentication no session is persisted server-side (stateless). The initial steps are the same. Credentials are exchanged against a token which is then attached to every subsequent request (it can also be stored in a cookie). However for the purpose of decreasing memory usage, easy scale-ability and total flexibility (tokens can be exchanged with another client) a string with all the necessary information is issued (the token) which is checked after each request made by the client to the server. There are a number of ways to use/create tokens:
Using a hash mechanism e.g. HMAC-SHA1
token = user_id|expiry_date|HMAC(user_id|expiry_date, k)
expiry_dateare sent in plaintext with the resulting hash attached (
kis only know to the server).
Encrypting the token symmetrically e.g. with AES
token = AES(user_id|expiry_date, x)
xrepresents the en-/decryption key.
Encrypting it asymmetrically e.g. with RSA
token = RSA(user_id|expiry_date, private key)
Production systems are usually more complex than those two archetypes. Amazon for example uses both mechanisms on its website. Also hybrids can be used to issue tokens as described in 2 and also associate a user session with it for user tracking or possible revocation and still retain the client flexibility of classic tokens. Also OAuth 2.0 uses short-lived and specific bearer-tokens and longer-lived refresh tokens e.g. to get bearer-tokens.
- Demystifying Web Authentication (Stateless Session Cookies)
Be aware of byte flipping attack if you use b) with CBC mode. http://resources.infosecinstitute.com/cbc-byte-flipping-attack-101-approach/ You may need to HMAC before encrypting to be able to detect alterations.
You must use authenticated encryption (AEAD or encrypt-and-MAC), not just encryption. In case of not using AEAD, you must authenticate after encrypting and you must check authentication before decrypting. This is not optional, encryption without authentication is useless.
Can you please clarify more why the session-based authentication is considered stateful?
@fujy In the session-based auth, the server is maintaining the client's login state: Is he/she/it logged in? For how much time? That information is indexed by the session id, but it is stored by the server in a database, file system or memory. It is not stored on the id itself.
what you meaning by "which is checked after each request made by the client to the server"? could you elaborate?
I am not quite sure stateless is exchangeable with token-based security. I believe token-based securities can be stateful with whitelist or blacklist approach. eg: you can store valid tokens in redis with certain ttl. In this case, is there any advantage over session based security when talking about scaleability?
for token based security approach 1, do you use the same signing secret for all users or different signing secrets? If the same one, how do you make sure it is secure? If different ones, where do you store them? If they are stored in DB or memory cache I would argue it has the same drawback as session based security which is making things "stateful"
HTTP is stateless, and in order to have an authenticated state, you need some kind of token used to reference information about the user. This session id is usually in the form of a random token sent as a cookie value. An OAuth Access Token is used to identify a user, and the
scopeof resources that user has access to. In applications that use OAuth single-sign on, an OAuth Access token typically is exchanged for a session id which can keep track of a wider variety of user state.
From an attacker's perspective, hijacking a session id, or OAuth Access Token, is as a good as a username and password, and sometimes it is even better. Session IDs must have security properties which protect user accounts from compromise.
From the developer's perspective, never reinvent the wheel. Use the session manager provided by your platform, and ensure it is configured to conform to the the OWASP Session Management guidelines.
I would even argue that hijacking a session id is worse than obtaining a username and password as it bypasses a number of security measures, such as two-factor authentication.
Thank you for your input, but I am more interested in token authentication without the cumbersome OAuth mechanism. These articles suggest this is being done and I just wanted to get some further information: https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/ http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
Note that ASP.NET violates the OWASP guidelines: The Web server does not store valid and expired authentication tickets for later comparison. This makes your site vulnerable to a replay attack if a malicious user obtains a valid forms authentication cookie - meaning that if a user logs out, all it does is delete the cookie client side. This part of the wheel I would reinvent.
So, on the session-based authentication, to increase the security in accessing resources which one is required:
- It should be used as a replacement for a user's credential
- It should always use a persistent cookie
- It should identify returning users to the website
- It should use 2-factor authentication