2

So I have written a dummy application, a login form written in angular2, this posts the username and password to a rest API, if the credentials are correct, the API returns a JWT (encoded in the JWT are various permissions).The JWT is saved in the local browser storage.

This works absolutely fine, the JWT stored in local storage (as per the guides I have read online) and can be accessed to anyone with a bit of browser knowledge (inspect element, view resources etc), and once you access the JWT token, it can easily be decrypted without the use of a key.

In my angular2 application, it decodes the key, if they key contains "value1 = True" it allows the user to a certain part of the website, if the key value is false, it returns the user to the home page with a access denied message. Again works fine in my test setup.

As the key is only stored locally, I can create a JWT anywhere, paste it into my browsers local storage with the correct credentials, and then I can access the restricted areas of the website.

Have a I missed anything, as this really doesn't seem secure? Lets say my app was online at mynewapp.com and the area mynewapp.com/private was protected with this JWT authentication, the application checked for a valid JWT, if a valid JWT token is found, it inspects the token, to see if it contains the relevent permissions to access this area, if it doesn't, whats to stop the person behind the browser modifying the contents of the browsers local storage, to manipulate the data to access this forbidden area.

The only way I can think of is to:

If JWT exists, perform API call to REST server, if the user with the JWT has permission to access the requested area, return true and allow the request to continue inside Angular

Else, REST Api returns false and user is not allowed any further.

2

If JWTs are used for authorization or authentication, they should be either signed or encrypted (which depends on your exact use case). If you have one auth resource and multiple other resources that want to consume the JWT, signing with a private key (in the auth resource), verifying with a public key (in the other resources) is a good pattern. If you have multiple servers all serving as auth endpoints and as resources, a shared encryption key can work well, as the token can be created and encrypted, then decrypted when it needs to be verified.

A JWT contains claims, but those claims, as you surmise, should not be manipulatable on the local side.

The folks at Auth0 (disclaimer: no relation to Auth0 at all) have a bunch more info about standard JWT signing algorithms.

One note - restrictions in Angular2 (like all client side pages) are only suitable for end user convenience - for example, hiding pages they can't access so they don't get confused. You should NEVER count on these, as any restrictions in Angular2/JS can be trivially bypassed. Before any restricted data is retrieved or restricted operations are performed, user authorization checks should be done on the SERVER. In fact, authorization checks should be done for every operation - you never trust the client, ever.

  • 1
    (note that the limitations above are not Angular2 issues, they are client side / JS issues in general - security cannot be implemented on the client side at all) – crovers Dec 19 '16 at 19:27
1

"Have I missed anything?"

Kind of - you've spotted certainly the main failing with JWT. That is doesn't actually provide much in the way of security. In particular, it is susceptible to "replay attacks".

As far as I know, there is no way to fully secure a system using just a JWT. You need to have additional checks on the server end.

A simple method might be. for example, creating and encrypted token on the server that included the originators IP address. You would compare the token against a fresh version on the server every few contacts from the browser (or every few seconds/minutes, depends on the type of application and how much data you are transferring). You restrict the number of checks in order to prevent DOS attacks.

By tuning how often you make the check, you can balance the server resource use against the security needed.

I'm sure there are many other ways of doing similar checks. You could also reduce risk by reducing the timeout on the token, this is not quite as secure but certainly helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.