Avoid REST service to be consumed twice - spring

I have a question about Spring MVC controllers scope and REST services. I have a couple of REST services, wich returns a token in the response so I can later recreate the state of the application, but I don't want the users use the same token twice, so I've decided to save an unique identifier inside the token and also in HttpServletRequest, so I can check it when I get the requests (a new identifier is generated in every request).
So, my questions are: 1) is there any other way to be sure that some user will not use the same token more than once (also considered to save that identifier in DB, but I would have lot of queries to insert, delete, verify, etc).2) is it ok for the controller that receives the requests to be a singleton, or should it be prototype? (considering that the identifier is taken from session and I don't want to mix it between different sessions).

A few words on tokens that are valid only once
It's not possible to achieve it
without keeping the track of the tokens somewhere. This security schema require some trade-offs, deal with it.
Give the user a token and keep the track of it on server side, just like a white list:
When a token is issued, add it to the white list.
When a request comes to the server with a token, check the white list and:
If the token is valid, accept the request and remove the token from the white list.
If the token is invalid, refuse the request by returning a proper status code such as 403.
Also, consider assigning an expiration date to the token and refuse any request that comes to the server with an expired token.
Regarding your performance concerns: Bear in mind that premature optimization is the root of all evil. You shouldn't optimize until you have a performance problem and you have proven that the performance problem comes from the way you store your tokens. You could start storing the tokens in the database and then consider a cache in memory, for example. But always be careful when fixing a problem that you currently don't have.
Working with JWT
If you go for JWT, there are a few Java libraries to issue and validate JWT tokens such as:
jjwt
java-jwt
jose4j
The jti claim should be used to store the token identifier on the token. When validating the token, ensure that it's valid by checking the value of the jti claim against the token identifiers you have on server side.
For the token identifier you could use UUID. In Java, it's as simple as:
String uuid = UUID.randomUUID().toString();

Since HttpSession#getId() is unique, you can use it to create an unique token:
// pseudo code
String token = httpSession.getId() + "-" + System.currentTimeMillis();
You can also create your own counter.

Here my two techniques to prevent it
Disable submit button:
We can disable submit button right before our function call HTTP request and enable it again after finish gets HTTP response. This technique is effective for the process that takes a long time to finish (more than 5 sec.). The user can not click n’ click again because of impatience to get the result. Additionally, we may show a loading box for a good experience.
Issue request token/id:
This technique actually more complicated and difficult to implement, but thanks to a good framework (such as Spring Boot) to make this easier. Before we are going to the code implementation, let’s talk about the mechanism first;
When form page is loaded, issue a new requestId
put issued requestId to HTTP header before calling the backend service
backend service identify a requestId is already registered or not
if requestId is already registered then we can mark as a violation request

Related

ADAL Mac returns 300 AD_ERROR_CACHE_MULTIPLE_USERS error

We are using the ADAL Mac library to authenticate. When using this library we get a 300 error (AD_ERROR_CACHE_MULTIPLE_USERS) with the description:
The token cache store for this resource contains more than one user. Please set the 'userId' parameter to the one that will be used.
When does this happen? How should one handle this scenario?
Background
ADAL has a token cache for all access/refresh tokens on the device. The cache keys on things like the user, resource being requested, etc.
The app can get into a state in which there are multiple tokens in the cache for the same request. While these tokens may represent something some different information, the information provided in the token lookup request was ambiguous in some way. Simple example:
Cache
hash(userA,B,C) -> token pair 1
hash(userB,B,C) -> token pair 2
hash(userA,F,G) -> token pair 3
Lookup (AcquireTokenSilent)
So now we do an AcquireTokenSilent request (cache lookup). This request doesn't require every pivot of the cache. For example,
AcquireTokenSilent(B, C)
There's ambiguity in this request, it could map to token pair 1 or 2.
Handling this Error
So there's two workarounds at this point:
Provide more information in the same request.
You can do a new AcquireTokenSilent request providing some more information that allows ADAL to definitively pick a cache entry. In this case, ADAL needs a userId meaning your app would need to store or lookup this value and pass it in the request. In our example,
AcquireTokenSilent(userA, B, C)
Ignore the cache and start from scratch.
If you cannot retrieve the userId and have no way to recover, your app can perform an interactive authentication request and ask the end user to enter their credentials. If you have a valid token, this is an adverse experience as your users will need to sign in more than necessary. This would just be a standard AcquireToken request. From our example (there's no user to request,
AcquireToken(B, C)

How to properly make one-off queries in CQRS system?

I have a system which gives an access to the set of resources via access tokens. So when clients need to access some particular resource they ask for the token (one resource - one token). I need to make one-off (or at least limited in time) token, to ensure even if tokens are leaked, they will soon become inactive.
What is the proper way to achieve that in CQRS based system? Querying the resource should not change the system state. In other words - we can't invalidate token in query handler. Can we?
These are different concerns. What I would do:
An edge check the authorisation (using the token provided) and
calls the query handler, together with the query/token info
Query returns the result
The edge publishes an event "TokenHasBeenUsed"
The edge returns the query result
Token provider consumes the event and invalidates the token.
You can also build it scheduling, invalidating the token after a while if not used. Plus, you can also have a usage counter or something and it all does not need to be blended to the edge or query handler.

How to invalidate previous JWT token after refresh

In our application new JWT token is returned in a cookie each time user sends a request, even though previous has still much lifetime. If user makes multiple request in a short period of time, there exists multiple valid tokens almost full lifetime on each. Browser is of course using the latest one, but someone may still use the previous ones to impersonate user.
Is there way to invalidate the previous token when dispatching a new one, or is the only choice to dispatch new token only when there is not much lifetime on the last one?
The only way to 'invalidate' tokens is by keeping track of them statefully.
This usually means doing something like keeping a key/value cache of tokens that are valid, and invalid, and checking incoming request tokens against these lists on each request.
The downside to doing things this way is that you lose a lot of the 'stateless' benefits of JWTs (since you are still checking a centralized store for token validity), but the benefit is that you can be more 'secure' by immediately revoking tokens you no longer want service-able.
One workaround is to have your access tokens be extremely short lived (5 minutes or so), to minimize any abuse.

Reason to discourage use of back or refresh button on net banking sites

I just want to know why refresh/back button is not recommended while using netbanking sites?
Is it because of session object that might get invalidated?
Your average banking site contains forms. To protect the user from accidentially performing some action by eg. clicking a link (or, more general, by some sort of request forgery), the forms can have an additional hidden field containing some random value.
That random value is also stored on the server side and used to check whether the form can contain parameters for a valid action (ie. the form token must match the server token).
The disadvantage is that, if you use the browser controls, you get back to the previous page, but probably without the server noticing. Thus, you use an old form token, the result being that the server will refuse to perform the specified action, because the form token does not match the server-side information.
As a side effect, this incident may lead to the currently active session to be terminated for security reasons.

Validate/Change Password via REST API

I want to change a user password via a REST API. This is not a forgotten or reset password function, but a logged in user wanting to change their password.
The form requires the current password, the new password, and a confirmation for the new password. However, I want to validate each form field as the user fills it out. This is trivial for newPassword and confirmNewPassword (client side), but not for currentPassword. Currently performing update to the User object via PUT /users/:id. If a password parameter is passed, I check for the currentPassword parameter and ensure it is correct prior to saving. However, for validation, I'm unsure of the best approach.
I also have a POST /users/validate - not sure if this is best either. This validates a User object for both create and update, but only validates fields that belong to the User object (email, username, password). currentPassword isn't one of these. Wondering how to handle this. Some things I've considered:
POST /users/check_password,
POST /users/validate (adding in validation for currentPassword if that parameter is passed, and check that currentPassword matches the users existing password) and
POST /users/:id/validate (separate validation for existing user, requiring currentPassword).
Any thoughts or advice would be greatly appreciated. My first application that only exposes functionality via REST API.
I'll start by pointing out that authentication is often handled outside of a REST model. When a user provides their credentials, they are not providing a REpresentation of their account object's STate (REST); nor is the response they receive such a representation. Because the user account resource state does not include both 'current' and 'new' passwords, the provision of both a 'current' and a 'new' password in a request can never truly fit under the REST model, but professionals often describe a 'continuum' of RESTfulness, with some APIs being completely RESTful and others falling between RPC (Remote Procedure Call) and REST.
It's not uncommon to have a RESTful component of an API that handles the serving of data models, and a more RPC component of an API that handles user accounts. You get to decide between the two. If your project includes super users that manage multiple user accounts, I would suggest trying to shoe-horn that into a REST API. If each user manages only their own account, I would suggest RPC.
If you've decided to use REST for account management, then you must choose an appropriate HTTP method (GET, POST, DELETE, HEADERS, etc). Clearly you require a method that will effect a change on the server (POST, PUT, DELETE, etc). In contrast to user orbfish's conclusion above, I'm going to say that PUT would be an appropriate method, under certain restrictions.
From RFC 2616, which formally defines our HTTP methods:
"Methods can also have the property of 'idempotence' in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent. "
Idempotency here means that if we make the same request n times in a row, the state of the server under the effects of the nth request will be the same as the state of the server under the effects of the first request. User orbfish correctly notes that if we make the request:
PUT /users/:id/account {current-password: 'a', new-password: 'b'}
and repeat it:
PUT /users/:id/account {current-password: 'a', new-password: 'b'}
that our first request should receive a response indicating success and our second request should receive a response indicating failure. However, the idempotency of PUT only requires that the state of the server is the same following both requests. And it is: after the first request the user's password is 'b' and after the second request the user's password is 'b'.
I mentioned restrictions above. You might want to lock a user out after m attempts to change a password unsuccessfully; this would provide security against brute-force password attacks. However, this would break the idempotency of the request: send a valid password request one time and you change your password, send it m more times and the server locks you out.
By specifying the PUT method, you are telling all clients that it's safe to send a request as many times as needed. If I as a client send a PUT request and our connection is interrupted such that I don't receive your response, I know that it is safe to send my PUT through again because it is idempotent: idempotency means that if you receive both requests it will be the same to your server as just receiving one. But if you're going to lock me out for an unsuccessful request, then it isn't safe to send a second request until I know whether you have received the first.
For this reason, you might consider PATCH or POST. I would suggest using PATCH. Whereas POST is described as either appending a new resource to a list or appending data to an existing resource, PATCH is described as a 'partial update' on a resource at a known URI. And unlike PUT, PATCH need not be idempotent.
I don't like /check_password or /validate because they're verbs; your first "update user" is better REST.
You can add the currentPassword to your User object as an unpersisted field, or as part of the Authentication header (username:password).
I would definitely change this from a PUT to a POST, though, because the same call with the same currentPassword cannot succeed twice (PUT is idempotent).
You are changing a property of the user resource (i.e., the password). If you use HTTP Basic for your authorization, you are already providing the current password, so there is no need to repeat it. I would simply PUT the entire user resource with the new password. Example:
PUT /users/fiddlerpianist HTTP/1.1
Content-Type: application/json
Authorization: Basic ZmlkZGxlcnBpYW5pc3Q6bXlub3Rzb2F3ZXNvbWVvbGRwYXNzd29yZA==
{
"password": "My awesome new password that no one will ever be able to guess!"
}
The other advantage of doing it this way is that you don't necessarily need to provide the old password, as long as you are a credentialed user that has access rights to modify the user resource. Maybe you're a customer support specialist who is never supposed to ask for the customer's old password but they are requesting a password change over the phone (after they've proven to you their identity and you've proven your identity to the system).
You want to avoid using a non-idempotent request in this case (such as PUT or PATCH), as that can lead to responses whose outcomes are uncertain (suppose the server returns a 500 for a non-idempotent request... you as the client have no idea what state the server left your resource in).
EDITED TO ADD: Note that, in a RESTful app, there is no concept of being "logged in." The communication from the client to the server is entirely stateless (it's the payload and method that communicates the state). Also, there really doesn't need to be a concept of validation the way you describe it, as a request to change the state of a resource can either be met with a 200 OK (if valid) or a 400 Bad Request (if invalid).
Another option is to create surrogate resources on user. If you're using HATEOAS you could link down to user/x/pwdchange from the user resource. And I want to clarify pwdchange is conceived as a noun/resource, not as a verb:
GET /user/jsmith/pwdchange List of password change requests (history)
POST /user/jsmith/pwdchange Create password change request, return id=1
GET /user/jsmith/pwdchange/1 Get password change resource, which would
include the outcome (success, failure, etc)
So, in short, I'm creating a resource named 'pwdchange' that is fully compliant with a REST view of the problem domain.
You might think about why you need to validate the current password as soon as it's entered. I've not seen a site do that. Second, it's perfectly fine to have a service that just validates something. Its called being practical verse beating yourself up trying to be RESTFul

Resources