Security Issues with RESTful Authentication & Session Management - rest

I'm trying to implement authentication and session management for a microservice. In order to do the process RESTfully, I understand that I'll need to use some kind of token-based authentication to avoid tracking client session data on the server. The following quote from this answer on the Information Security Stack Exchange nicely sums up my understanding of the implementation:
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 a string with all the necessary information is issued (the token) which is checked after each request made by the client to the server.
From this, I understand how stateless session maintenance is advantageous for scalability, and flexibility as explained. But it seems to me that this leaves the application exposed to some serious problems:
If a hacker somehow intercepts the credential exchange HTTP REST call, they could execute replay attacks on the server get all the information they want.
In fact, since the session token is stored on the client side, couldn't a hacker just retrieve the requisite information from LocalStorage/SessionStorage by debugging the app? Or by monitoring the incoming and outgoing HTTP calls using dev tools? If they get the required token information (even encrypted token information), they could simply start faking REST calls to the server from another window and get all the data they want!
Finally, even if you do give the client a session token, wouldn't the server still have to authenticate that token? In effect, the server would have to maintain session tokens to user mappings...but doesn't that defeat the purpose of a stateless REST-based architecture?
Maybe I am seeing these problems because there is a gap in my understanding. If that's the case, I'd like some clarity of the basic concepts. If not, I'd like to know if there are any techniques to address these specific problems.

Related

Does Using Opaque Access Tokens Make My Server Stateful?

I am trying to understand statelessness in restful APIs in the context of authentication. Here's the scenario:
The user logs in.
The server verifies the username and the password, and generates an opaque access token. It caches some information related to this token - for example, the expiration time, the userId, whether this token was explicitly invalidated before it expired, etc.
The token is sent to the client, and the client sends it with every future request.
List item
Fielding's dissertation defines statelessness as:
"...such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client."
In my example, the client is sending the token with every request, so the first condition is satisfied. However, my server has a context associated with this session that is stored in the sessions cache.
Does this make my application stateful?
If yes, then is it that true statelessness be achieved only if we are using JWTs? I am pondering upon this as JWTs are quite new, so how were architects building truly stateless services before they were invented?
That's right. If you you maintaining the session you are keeping the state in server which makes the application hard to scale. True stateless applications can be scaled out and any server should be able to handle the request.
JWT is popular way to avoid sessions and everything is encapsulated inside the token for any server to auth/Authorize the request and help us achieve stateless application, they come with their own challenges however OpenID connect is the new way for Auth/Authorization.
Before jwt to make application stateless we used to keep session in DB (or Shared Cache) , and any server would like to check the session would have to contact DB.
Hope that Helps!
Briefly: No, such usage of token does not make your application stateful.
Detailed: When we talk about stateless/stateful, we consider usually only the data that affect business logic. Business logic does not usually depend on authentication data. For example, a user sends a request that contains all data needed to place some order. Normally creating an order does not depend on when this user has logged in, on his user ID, etc.

Can I use a session identifier in a REST API? [duplicate]

Is using sessions in a RESTful API really violating RESTfulness? I have seen many opinions going either direction, but I'm not convinced that sessions are RESTless. From my point of view:
authentication is not prohibited for RESTfulness (otherwise there'd be little use in RESTful services)
authentication is done by sending an authentication token in the request, usually the header
this authentication token needs to be obtained somehow and may be revoked, in which case it needs to be renewed
the authentication token needs to be validated by the server (otherwise it wouldn't be authentication)
So how do sessions violate this?
client-side, sessions are realized using cookies
cookies are simply an extra HTTP header
a session cookie can be obtained and revoked at any time
session cookies can have an infinite life time if need be
the session id (authentication token) is validated server-side
As such, to the client, a session cookie is exactly the same as any other HTTP header based authentication mechanism, except that it uses the Cookie header instead of the Authorization or some other proprietary header. If there was no session attached to the cookie value server-side, why would that make a difference? The server side implementation does not need to concern the client as long as the server behaves RESTful. As such, cookies by themselves should not make an API RESTless, and sessions are simply cookies to the client.
Are my assumptions wrong? What makes session cookies RESTless?
First of all, REST is not a religion and should not be approached as such. While there are advantages to RESTful services, you should only follow the tenets of REST as far as they make sense for your application.
That said, authentication and client side state do not violate REST principles. While REST requires that state transitions be stateless, this is referring to the server itself. At the heart, all of REST is about documents. The idea behind statelessness is that the SERVER is stateless, not the clients. Any client issuing an identical request (same headers, cookies, URI, etc) should be taken to the same place in the application. If the website stored the current location of the user and managed navigation by updating this server side navigation variable, then REST would be violated. Another client with identical request information would be taken to a different location depending on the server-side state.
Google's web services are a fantastic example of a RESTful system. They require an authentication header with the user's authentication key to be passed upon every request. This does violate REST principles slightly, because the server is tracking the state of the authentication key. The state of this key must be maintained and it has some sort of expiration date/time after which it no longer grants access. However, as I mentioned at the top of my post, sacrifices must be made to allow an application to actually work. That said, authentication tokens must be stored in a way that allows all possible clients to continue granting access during their valid times. If one server is managing the state of the authentication key to the point that another load balanced server cannot take over fulfilling requests based on that key, you have started to really violate the principles of REST. Google's services ensure that, at any time, you can take an authentication token you were using on your phone against load balance server A and hit load balance server B from your desktop and still have access to the system and be directed to the same resources if the requests were identical.
What it all boils down to is that you need to make sure your authentication tokens are validated against a backing store of some sort (database, cache, whatever) to ensure that you preserve as many of the REST properties as possible.
I hope all of that made sense. You should also check out the Constraints section of the wikipedia article on Representational State Transfer if you haven't already. It is particularly enlightening with regard to what the tenets of REST are actually arguing for and why.
First, let's define some terms:
RESTful:
One can characterise applications conforming to the REST constraints
described in this section as "RESTful".[15] If a service violates any
of the required constraints, it cannot be considered RESTful.
according to wikipedia.
stateless constraint:
We next add a constraint to the client-server interaction:
communication must be stateless in nature, as in the
client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3),
such that each request from client to server must contain all of the
information necessary to understand the request, and cannot take
advantage of any stored context on the server. Session state is
therefore kept entirely on the client.
according to the Fielding dissertation.
So server side sessions violate the stateless constraint of REST, and so RESTfulness either.
As such, to the client, a session cookie is exactly the same as any
other HTTP header based authentication mechanism, except that it uses
the Cookie header instead of the Authorization or some other
proprietary header.
By session cookies you store the client state on the server and so your request has a context. Let's try to add a load balancer and another service instance to your system. In this case you have to share the sessions between the service instances. It is hard to maintain and extend such a system, so it scales badly...
In my opinion there is nothing wrong with cookies. The cookie technology is a client side storing mechanism in where the stored data is attached automatically to cookie headers by every request. I don't know of a REST constraint which has problem with that kind of technology. So there is no problem with the technology itself, the problem is with its usage. Fielding wrote a sub-section about why he thinks HTTP cookies are bad.
From my point of view:
authentication is not prohibited for RESTfulness (otherwise there'd be little use in RESTful services)
authentication is done by sending an authentication token in the request, usually the header
this authentication token needs to be obtained somehow and may be revoked, in which case it needs to be renewed
the authentication token needs to be validated by the server (otherwise it wouldn't be authentication)
Your point of view was pretty solid. The only problem was with the concept of creating authentication token on the server. You don't need that part. What you need is storing username and password on the client and send it with every request. You don't need more to do this than HTTP basic auth and an encrypted connection:
Figure 1. - Stateless authentication by trusted clients
You probably need an in-memory auth cache on server side to make things faster, since you have to authenticate every request.
Now this works pretty well by trusted clients written by you, but what about 3rd party clients? They cannot have the username and password and all the permissions of the users. So you have to store separately what permissions a 3rd party client can have by a specific user. So the client developers can register they 3rd party clients, and get an unique API key and the users can allow 3rd party clients to access some part of their permissions. Like reading the name and email address, or listing their friends, etc... After allowing a 3rd party client the server will generate an access token. These access token can be used by the 3rd party client to access the permissions granted by the user, like so:
Figure 2. - Stateless authentication by 3rd party clients
So the 3rd party client can get the access token from a trusted client (or directly from the user). After that it can send a valid request with the API key and access token. This is the most basic 3rd party auth mechanism. You can read more about the implementation details in the documentation of every 3rd party auth system, e.g. OAuth. Of course this can be more complex and more secure, for example you can sign the details of every single request on server side and send the signature along with the request, and so on... The actual solution depends on your application's need.
Cookies are not for authentication. Why reinvent a wheel? HTTP has well-designed authentication mechanisms. If we use cookies, we fall into using HTTP as a transport protocol only, thus we need to create our own signaling system, for example, to tell users that they supplied wrong authentication (using HTTP 401 would be incorrect as we probably wouldn't supply Www-Authenticate to a client, as HTTP specs require :) ). It should also be noted that Set-Cookie is only a recommendation for client. Its contents may be or may not be saved (for example, if cookies are disabled), while Authorization header is sent automatically on every request.
Another point is that, to obtain an authorization cookie, you'll probably want to supply your credentials somewhere first? If so, then wouldn't it be RESTless? Simple example:
You try GET /a without cookie
You get an authorization request somehow
You go and authorize somehow like POST /auth
You get Set-Cookie
You try GET /a with cookie. But does GET /a behave idempotently in this case?
To sum this up, I believe that if we access some resource and we need to authenticate, then we must authenticate on that same resource, not anywhere else.
Actually, RESTfulness only applies to RESOURCES, as indicated by a Universal Resource Identifier. So to even talk about things like headers, cookies, etc. in regards to REST is not really appropriate. REST can work over any protocol, even though it happens to be routinely done over HTTP.
The main determiner is this: if you send a REST call, which is a URI, then once the call makes it successfully to the server, does that URI return the same content, assuming no transitions have been performed (PUT, POST, DELETE)? This test would exclude errors or authentication requests being returned, because in that case, the request has not yet made it to the server, meaning the servlet or application that will return the document corresponding to the given URI.
Likewise, in the case of a POST or PUT, can you send a given URI/payload, and regardless of how many times you send the message, it will always update the same data, so that subsequent GETs will return a consistent result?
REST is about the application data, not about the low-level information required to get that data transferred about.
In the following blog post, Roy Fielding gave a nice summary of the whole REST idea:
http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841
"A RESTful system progresses from one steady-state to the
next, and each such steady-state is both a potential start-state
and a potential end-state. I.e., a RESTful system is an unknown
number of components obeying a simple set of rules such that they
are always either at REST or transitioning from one RESTful
state to another RESTful state. Each state can be completely
understood by the representation(s) it contains and the set of
transitions that it provides, with the transitions limited to a
uniform set of actions to be understandable. The system may be
a complex state diagram, but each user agent is only able to see
one state at a time (the current steady-state) and thus each
state is simple and can be analyzed independently. A user, OTOH,
is able to create their own transitions at any time (e.g., enter
a URL, select a bookmark, open an editor, etc.)."
Going to the issue of authentication, whether it is accomplished through cookies or headers, as long as the information isn't part of the URI and POST payload, it really has nothing to do with REST at all. So, in regards to being stateless, we are talking about the application data only.
For example, as the user enters data into a GUI screen, the client is keeping track of what fields have been entered, which have not, any required fields that are missing etc. This is all CLIENT CONTEXT, and should not be sent or tracked by the server. What does get sent to the server is the complete set of fields that need to be modified in the IDENTIFIED resource (by the URI), such that a transition occurs in that resource from one RESTful state to another.
So, the client keeps track of what the user is doing, and only sends logically complete state transitions to the server.
As I understand, there are two types of state when we are talking about sessions
Client and Server Interaction State
Resource State
Stateless constraint here refers to the second type in Rest. Using cookies (or local storage) does not violate Rest since it is related to the first.
Fielding says: 'Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.'
The thing here is that every request to be fulfilled on the server needs the all necessary data from the client. Then this is considered as stateless. And again, we're not talking about cookies here, we're talking about resources.
HTTP transaction, basic access authentication, is not suitable for RBAC, because basic access authentication uses the encrypted username:password every time to identify, while what is needed in RBAC is the Role the user wants to use for a specific call.
RBAC does not validate permissions on username, but on roles.
You could tric around to concatenate like this: usernameRole:password, but this is bad practice, and it is also inefficient because when a user has more roles, the authentication engine would need to test all roles in concatenation, and that every call again. This would destroy one of the biggest technical advantages of RBAC, namely a very quick authorization-test.
So that problem cannot be solved using basic access authentication.
To solve this problem, session-maintaining is necessary, and that seems, according to some answers, in contradiction with REST.
That is what I like about the answer that REST should not be treated as a religion. In complex business cases, in healthcare, for example, RBAC is absolutely common and necessary. And it would be a pity if they would not be allowed to use REST because all REST-tools designers would treat REST as a religion.
For me there are not many ways to maintain a session over HTTP. One can use cookies, with a sessionId, or a header with a sessionId.
If someone has another idea I will be glad to hear it.
i think token must include all the needed information encoded inside it, which makes authentication by validating the token and decoding the info
https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/
No, using sessions does not necessarily violate RESTfulness. If you adhere to the REST precepts and constraints, then using sessions - to maintain state - will simply be superfluous. After all, RESTfulness requires that the server not maintain state.
Sessions are not RESTless
Do you mean that REST service for http-use only or I got smth wrong? Cookie-based session must be used only for own(!) http-based services! (It could be a problem to work with cookie, e.g. from Mobile/Console/Desktop/etc.)
if you provide RESTful service for 3d party developers, never use cookie-based session, use tokens instead to avoid the problems with security.

How to understand "RESTful API is stateless"?

I heard that a "RESTful API should be stateless. All state info should be kept on client side".
But when I issue an AJAX call from a web page, I noticed that a session ID cookie is always sent along to the server. With that session ID, I can obtain the session object on the server, and thus I can "get/set some state info in the session".
Does this break the "code of being stateless" for a RESTful API?
ADD 1
(The background of my question is as below.)
I tried to implement a login page by calling a RESTful API to validate a username and a password.
Each time a user attempts to visit a page of my site, a login servlet filter will check the session (this is where getSession() gets called) for that user to see if valid login info exists. If not, the login filter will redirect the user to the login page.
On the login page, an AJAX call is made to a RESTful API on the server with the username and the password. Depending on the result of that RESTful API call, the JavaScript on the page will decide whether to let the user into my site.
So, in this scenario, I kind of have to use session.
The detailed code is located here:
Is this login logic via RESTful call sound?
Simply put: In REST applications, each request must contain all of the information necessary to be understood by the server, rather than be dependent on the server remembering prior requests.
Storing session state on the server violates the stateless constraint of the REST architecture. So the session state must be handled entirely by the client.
Keep reading for more details.
The session state
Traditional web applications use remote sessions. In this approach, the application state is kept entirely on the server. See the following quote from Roy T. Fielding's dissertation:
3.4.6 Remote Session (RS)
The remote session style is a variant of client-server that attempts to minimize the complexity, or maximize the reuse, of the client components rather than the server component. Each client initiates a session on the server and then invokes a series of services on the server, finally exiting the session. Application state is kept entirely on the server. [...]
While this approach introduces some advantages, it reduces the scalability of the server:
The advantages of the remote session style are that it is easier to centrally maintain the interface at the server, reducing concerns about inconsistencies in deployed clients when functionality is extended, and improves efficiency if the interactions make use of extended session context on the server. The disadvantages are that it reduces scalability of the server, due to the stored application state, and reduces visibility of interactions, since a monitor would have to know the complete state of the server.
The stateless constraint
The REST architectural style is defined on the top of a set constraints that include statelessness of the server. According Fielding, the REST stateless constraint is defined as the following:
5.1.3 Stateless
[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]
This constraint induces the properties of visibility, reliability, and scalability:
Visibility is improved because a monitoring system does not have to look beyond a single request datum in order to determine the full nature of the request. Reliability is improved because it eases the task of recovering from partial failures. Scalability is improved because not having to store state between requests allows the server component to quickly free resources, and further simplifies implementation because the server doesn't have to manage resource usage across requests.
Authentication and authorization
If the client requests protected resources that require authentication, every request must contain all necessary data to be properly authenticated/authorized. See this quote from the RFC 7235:
HTTP authentication is presumed to be stateless: all of the information necessary to authenticate a request MUST be provided in the request, rather than be dependent on the server remembering prior requests.
And authentication data should belong to the standard HTTP Authorization header. From the RFC 7235:
4.2. Authorization
The Authorization header field allows a user agent to authenticate itself with an origin server -- usually, but not necessarily, after receiving a 401 (Unauthorized) response. Its value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested. [...]
The name of this HTTP header is unfortunate because it carries authentication instead of authorization data.
For authentication, you could use the Basic HTTP Authentication scheme, which transmits credentials as username and password pairs, encoded using Base64:
Authorization: Basic <credentials>
If you don't want to send the username and password in each request, the username and password could be exchanged for a token (such as JWT) that is sent in each request. JWT can contain the username, an expiration date and any other metadata that may be relevant for your application:
Authorization: Bearer <token>
What might be wrong with your server
Once you have a session indentifier, I guess a HTTP session is being created somewhere in your application. It can be in your own code or in the code of the framework you are using.
In Java applications, you must ensure that the following methods are not getting invoked:
HttpServletRequest#getSession()
HttpServletRequest#getSession(boolean) with true

Maintaing credentials in a stateless RESTful web service between calls

I'm writing a rest web service which authenticates and authorizes against an LDAP server. The problem is that calls to the LDAP server are somewhat expensive due to the way everything is configured. Consequently I am trying to minimize the number of calls I have to make to it.
In a normal stateless design, each call to the rest backend just be authenticated and authorized. I'm trying to figure if/how I can accomplish this without having to contact the LDAP server each time.
I've been toying with the idea of using a custom token upon initial login and require the client to return the token at each request, but short of encrypting the token or signing it, I can't think of a secure mechanism that would allow me to do this. But to encrypt a new token at each response, and decrypt at each request will put extra overhead that I would gladly avoid as well.
Caching the LDAP response is a concept as well, but then that opens to a whole bunch of other concerns as well (cache life, clustering, etc).
Is there a mechanism that I can use to accomplish this?

Way to maintain a session in a REST application

We have a REST application that is utilized mostly by applications that dont need to maintain their state, so till date we have been quiet "RESTFUL" without maintaining a state. We use the Private/Public (similar to Amazon) for authentication.Currently the client passes the credentials for every request
Now we have a new requirement where we have to maintain the state (or conversation).The client can be a Rich application or a hand held device .I am trying to comeup with the best way to implement the state .Should we pass on a session Id and maintain that ID ..is that the best and the only solution ?
Passing on a session ID is not the only way and not the best way to maintain conversational state. The best way, if you have a RIA is to maintain the state on the client itself, where it belongs, as some of the comments suggest. This means still sending the credentials every request.
Re-authentication on every request is the only way, and if you feel that there's a performance hit on the server, the server can (as suggested) cache the result of an authentication request for a period of time. Digest authentication could help avoid caching responses by cryptograpically signing the tokens going over the wire.
If that's not good enough you could use something akin to Google ClientLogin, and giving the client an encrypted token that can be verified without needing to ask an authorization, and without passing the user's real credentials over the wire. Google themselves this by doing the login over https, and then using the generated tokens over http. It's open for replay attacks for the lifetime of the token.