Sanish Joseph
Sanish Joseph

Reputation: 2266

Anti-forgery token on each request from angular app

I have a website which supposed to be very secure as most of the activities are financial transactions. This site has a lot of security mechanism and I doubt one of that is not sufficient.

This web application is based on AngularJS 1.4 and ASP.NET MVC 4. After logging into the system using angular, I am calling a controller action to set Anti-forgery token. The all subsequent request has the same token and server validates the same on each request.

Now the problem.

Since we are not changing the token on each request, a logged in user can use the token from the request by merely looking in Fiddler or Chrome Network tab and try to request resources modifying the request.

Is it required to reset the token on each request? Will it help to prevent this kind of attacks?

Upvotes: 0

Views: 1057

Answers (1)

AaronLS
AaronLS

Reputation: 38392

The token is not meant to prevent the authorized user from crafting requests manually. The token ensures that someone else other than they user, cannot use a csrf request to forge a request from the user.

You can reuse the same token because if implemented properly, a potential CSRF attacker should not be able to read the value. This relies on the same origin policy of the browser to ensure the third party site cannot read or submit the same value.

If you had any kind of hole though, such as a json GET that returned a token(best practice is JSON returning data should still be submitted with a post) then the token could be compromised.

https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

Authorization In regards to potentially fraudulent requests from the authenticated user

You need server side checks that ensure that he is only posting edits to accounts for which he has the authority to edit. For example, if I own account A, and I want to send money to account B, then the server side check will ensure that I own account A, and thus have authority to send its funds elsewhere. If I hand crafted a request to send funds from B to A, the server side check should see that I am not the owner of B by looking at the database relations of the account and owner. This is known as authorization. Authorization ensures that a user has the authority to perform an action. This is usually dictated by business rules that defines the relationships between tables that say who has access to what.

Authentication The only other issue is ensuring that I am who I say I am, since if I just posted a user ID in the request, I could easily change that in the browser.

When the user proves he is who he says he is, usually by providing userid/password, then we generate an authentication token. In ASP.NET this token is cryptographically secure such that only the server has the necessary key information to generate and validate the token. Usually this token is persisted as a cookie.

The combination of authentication and authorization ensures we know who the user is, and on each request use our business rules defining authorization to check that the action is valid. It doesn't matter that he can hand craft invalid requests, as the requests will fail server side authorization.

Imagine this simplified server side code:

public void TransferFunds(TransferFundsRequest request)
{
  var account = Database.GetAccount(request.SourceAccountId);
  if(account.OwnerUserId != session.UserId)
  {
     throw UnauthorizedException("This user is not the owner of the source account in the transfer funds request.");
  }

  // continue with logic to transfer funds
} 

CSRF Cross site request forgery is an entirely different issue. This is when somehow another site loaded in the authorized user's browser tries to send a request from the user's browser. A malicious third party site that I visit uses javascript or other methods to cause my browser to make a TransferFunds request, from account A to account C. Now if I am owner of account A, from the perspective of the server that is a valid request. CSRF tokens ensure that we can detect that the user did not send the request from a form that our server generated, but instead some third party site's form or URL.

For example, if all the parameters of the request can be coded in a query string, I could craft a URL for the TransferFunds request and email it to the Account A owner and try to trick them into clicking the link. If the user happens to be logged into the site, then our server believes the user sent the request. However, if we include the anti-CSRF token when generating HTML input forms, then the absence of the token proves to us that the request came from a form or URL crafted by a third party.

Upvotes: 2

Related Questions