0
votes

I have a ASP.NET core REST API deployed in a Server behind IIS. REST API is consumed by Angular JS Web application and Mobile(Android/IOS) application. For Authorization I'm using JWT token(). Recently went through Security Audit and they found that JWT stored in Local storage can be stolen and used by other attacker from the same organization for impersonation(For eg, Employee utilizing Manager's features).

I want to tag the person or that machine to that JWT so that when the JWT is stolen the attacker cannot misuse it or will not be any use with that stolen Token. I tried tagging the IP with JWT token and stored those lookup in Server(In memory Cache). Below is the code i tried , which didn't work.

private readonly IHttpContextAccessor _httpContextAccessor;
public TestController(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}
var ipAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();

I expected output to be different every time i request from different machines. But the actual output is same IP every time like this 15.11.101.25 (though i tried from different machines). Please share with me some better solution if there is any. Excuse my English.

1
Well, if you use a proxy or a common internet connection, then its normal that all IPs are same. You should try it from a mobile device (thats not connected via WLAN). Also how is a stolen token related to CSRF? CSRF happens, when an attacker forges a link (or form on a page and lures you to visit it, so a hidden form is sent). With JWT this can't happen, CSRF is only vulnerable to Cookie authentication, because the browser automatically sends the cookie with the request, which doesn't happen with JWTTseng
CSRF can't get the tokens from local storage, that's only possible with XSS (Cross-Site Scripting), when someone manages to inject a piece of JavaScript Code into your website (when you don't properly sanitize your user input). Also the scenario that an employee gets the managers JWT token is unlikely unless a) they have physical access to the managers computer (then you have other, way bigger issues in your company) or b) the user can inject a javascript code into the website and have the manager open it, in which case you have serious trust issues with your employeesTseng
@Tseng We can try from Mobile device. But the problem is it should work for Web as well. Sorry for diverting this question towards CSRF. Main problem is I should avoid User B stealing User A's token, so that User B can't impersonate as User A.vinothvs
What I meant to say, if all the users of the same company have the Same IP (they share the same public IP via one internet connection), using the IP as discriminator is pointlessTseng
@Tseng : I mentioned exactly same thing to our Security experts("that an employee gets the managers JWT token is unlikely unless they have physical access to the managers computer). But they are not ready to listen. So need to find some solution to tag it. They expect this application to behave like traditional session concept. Like every session is different and one cannot steal others session. For the sake of argument still i can argue on hacking the application if the hacker managed to get the Session cookie. But Security team is not ready for any debate.vinothvs

1 Answers

3
votes

If you really need that kind of security, you can combine the JWT token with a secure (=cookies only allowed to be sent via https) http-only cookie, and store a kind of request token inside it that sent on each request.

You can have a read on Where to Store your JWTs – Cookies vs HTML5 Web Storage which kind of covers the topic and explain the up- and down-sides of local storage vs cookies for JWT.

Http-only cookies can't be read via JavaScripts (and hence not stolen) and are hence secure against XSS attacks. And CSRF based attacks can't get the JWT token (since its sent via headers).

So XSS based attacks won't have the cookie based token and CSRF based request won't have the JWT token required to authenticate the user. The cookie token could be generated on sign in, so its tied to the user who logs on that machine.

You can of course also turn it around and have the JWT in a secured cooke and the anti request token as header.

Of course you could still steal the anti-forgery cookie with physical access to the machine, but that's neither XSS nor CSRF and can't be protected by the application alone, the machines themselves need to be secured against physical type of attacks.

Alternatively, don't store JWT tokens in the local storage. When you use the OpenID flow, your application will, on the first load, see that its not authorized, will redirect you to the OpenID provider, let the user enter his credentials and redirect them back with the token (or code for the auth code flow).

When the user closes the browser and opens the site again, there's no token anymore, the user will be redirected to the OpenID provider. Since the user is still logged in, no credentials will be asked and he will be redirected back to the page he came from, including a new set of tokens. You just need the store the tokens in memory (and refresh when it expires) for the current application session.