I'm thinking about making an app with javascript and make it a SPA.
Using JWT tokens to authenticate the users and set the user roles on the app, what is the best way to protect sensitive content?
Using html templates for logged pages is bad? Should i return always the sensitive content from the api?
Thanks
Everything dynamic should be passed through your web service. If you won't use anything improperly (like using SQL drivers without injection prevention) there won't be anything unsafe (for at least first stage).
Also, to prevent MiM attacks, you should use SSL/TLS.
You can encrypt your JWT. Such encryption is defined in the RFC7516.
Depending on the programming language used on server side and client side (JS) , you may find libraries that support the JWE.
At jwt.io, you will find a list of those libraries.
Related
I have an Electron Application that needs to connect to an external PouchDB / CouchDB and a FTP-Server to retrieve some data. So in my Code I use
remoteDB = new PouchDB('http://my-Couch-User:my-Couch-Password#123.456.789.225:5984/myDB');
ftp.connect({host: ServerIPAddress), user: 'my-FTP-user', password: 'my-FTP-Password'});
I'm not working with highly confidential data, but having my passwords for external servers disclosed in such an easy readable form gives me the goosebumps.
Does anybody have an Idea how to at least hide them a little bit? (I know there is no way of really securing them under JavaScript)
Consider storing the confidential data in environment variables and access them via process.env.FTP_USERNAME and process.env.FTP_PASSWORD, for example.
Passwords or tokens really shouldn't be hardcoded and readable.
If you have a lot of configuration values, credentials or tokens, then you can consider using dotenv (https://www.npmjs.com/package/dotenv) or something similar.
Edit
Now that we learned about the OP requirements with his comments below this answer...
It is not possible to hide passwords in any application. It will always be possible to extract them.
Consider changing the server side code so that your applications don't talk with the FTP server directly but with a proxy where credentials are not required. The proxy then talks to the FTP server and the credentials will not be exposed.
Consider using a system that provides access via tokens in addition to credentials. You could ask users to login with their personal credentials and the system could generate and send personal access tokens for the server.
if you don't want to have them on the code and you don't want users to login with their own credentials, then I can only think of either having them on a separate file that compiles the info or do a request to a server that generates session data for the app.
But people with a bit of knowledge would still have ways to get the info in both cases.
I'm new to anything to do with user authentication in general, both front and backend. I'm looking in to building an application that uses Elasticsearch with Angular 2/5. There's not a lot of information (I've found some) about how to build an Angular 2+ app with Elasticsearch, particularly in regards to authentication, and user role management. But researching how to accomplish this, I've found this tutorial by Jason Watmore that I will try to adapt to Elastic. I see in the comments, Jason explains that for sites where you want the front-end to be secure, it is advisable to do authentication in a separate front-end app, and then redirect the user to the full app, once the user has logged in. The reason being that no front-end app is secure, in that a user could alter variables to view routes that are protected by route guards, or other ways. That data is still secure from the back-end, but you have features you don't want the public knowing about in the front-end, like how you are analyzing data entered by users.
My first (but secondary) question is, in regards securing a front-end application, is this an absolute truth that it isn't possible? It makes sense, and I have a hunch it is true, but I was wondering if there are ways to at least make it very difficult to view guarded routes. (Like the route guard asks the server if the token is valid?... But then you could just mod the function to always return true, right? Hmm...)
Anyways, it's looking like my application will need three parts in lieu of this. The login/registration, the public side where the standard route guards are sufficient, and an admin that will need to be entirely hidden from the public.
With Elasticsearch, (I think) there's an opportunity to develop our application entirely without backend coding, since X-pack provides security and features for managing user roles... Except for maybe one thing: I'm not sure how to keep the front-end of the admin from the public. Will this require some backend work? Update: This was what someone else was telling me early on. It isn't true.
With Elasticsearch, (I think) there's an opportunity to develop our application entirely without backend coding, since X-pack provides security and features for managing user roles.
It's possible, but not recommended. The Elasticsearch API is not designed to be consumed directly by a front end client, and the security constraints that are put in place within X-Pack do not aim to be secure within that environment.
Elastic recommends that you communicate with Elasticsearch from a backend process.
There are elasticsearch clients for many languages including python and node, so you can use whatever backend technology you prefer.
This is a design question for AngularJS websites that access a REST API. Since all the AngularJS code can be viewed from the client side (assuming obfuscation is not completely secure) how do you hide the API access credentials (the API key and password or even a JWT)?
This can be extended to a broader question about how other application logic can be hidden in an AngularJS website?
My research led me to some insights, one of which was
http://billpatrianakos.me/blog/2016/02/15/securing-api-keys-in-a-javascript-single-page-app/
But this has me more confused now, since the post suggests an SPA connecting to a REST API is not a good architecture. I thought it was and now can't figure what the right approach is.
The closest I can come to an answer is this resource:
https://developers.facebook.com/docs/facebook-login/security#appsecret
Facebook, is pretty good with their security and say:
Never include your App Secret in client-side or decompilable code.
Use unique short-term tokens on clients.
In short, do not keep API secrets on the client side
Answering the discussion in comments for sake of not being brief:
And then my question would be "what then is the correct architecture for SPAs and server side code (or database access)?".
There's no one correct architecture, it depends on the size and scope of your project. It will also depend on what frontend and backend frameworks you choose. Those choices also will depend on how many other APIs you are calling, or what other developers or you are most familiar with.
Speaking more specifically about security though, ideally you'd like to set up a session for the user which consists of a token that the user uses to identify himself. This is usually generated for each user by the server when they login. Generally this is provided by the framework you are working in, but even if it isn't, it's fairly simple to build. You will want to prevent cross origin requests (making sure the user is actually on YOUR frontend) and have secure connections (setting up SSL and https, though this can get complicated). You will generally want to run your JS code through something like Uglify to prevent it from being too easy to look through, but this does NOT guarantee that people cannot take that code and un-uglify it.
As the other answers have suggested, you should never keep API keys or any secrets in the client source code. There is no way to hide anything on the client, and obfuscation != security.
If you are looking to architect secure authentication/authorization into your app, you will want to return a JWT to the AngularJS application. You can then pass this JWT as a Bearer token to your API which will verify the validity of the token and allow the API to authorize access to the AngularJS application.
As for where to store the JWT token, you can store it in either Local Storage or in a cookie. There are serious considerations between choosing whether to store the token in either of these locations.
If security is your concern, I would look into the OAuth 2.0 Implicit Flow.
Don't put API keys in your client side source code. Keep them on your server, and have your client make a request to YOUR server, which then calls out to external APIs for data.
I have been following this tutorial on how to create JWT authorization in an asp.net Web API application.
In my case the authentication server will be the same server holding the resources (ie all done in the one asp.net Web API application), so I can see that sharing the "secret" used in encoding the JWT is not a problem when it come to the route authentication and authorization.
However, I will have have an Mobile application (using the Ionic framework) where I would like to be able to validate and decode the JWT so that I can enable/disable different parts of the UI. So I will need to do this in JavaScript.
So, I would not want the application to have access to this "secret" string used to encode the JWT.
My questions are
How can I both validate and decode a JWT without having to have this "secret" key?
Reading other posts, perhaps the validation is not possible, but decoding is. In this case there is the possibility of incorrect UI enabling, but in the end the web API call will fails as this can do the validation as well. Is this the correct way to go about it
Is there another way of creating the JWT where we have private and public key, so the JavaScript can have the public key and use this for the validation?
Thanks in advance for any help!
You can use signing algorithms like RS256 that are based on asymmetric cryptography. This means that signing a token requires access to a private key, which can be safely stored server-side, and validating requires only access to a public key.
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with HMAC algorithm) or a public/private key pair using RSA.
(source: Learn JSON Web Tokens; emphasis is mine)
As you mentioned, the decisions you make on the client application running on a user device should only be done from a user experience perspective and all authorization decisions should still be done again on the server-side.
The best analogy is the Javascript form validation that can be done on the browser to provide the user with instant feedback but that still requires the same or even greater validation to be done on the server-side as an attacker could easily bypass the client-side ones.
Additionally, you should take in consideration:
This interpretation of a token by a client application despite the fact that the token is intended for use in the API is acceptable if you're okay with having a really tight relationship between the client application and the resource server. From your description, all the parts of the system are under your control so this seems fine.
The use of RSA256 has associated performance costs when compared with the use of HS256 which is based on the shared secret you mentioned. If this is an issue you can even question yourself if you really need to validate the token client-side; if all the decisions you make are purely cosmetic why bother with the validation. The premise would be that someone trying to provide a fake token would only see options or links that would immediately fail when accessed due to the server-side rejecting the token
I have implemented json web service in java(server) and client is in pure javascript. It is possible to authenticate web service call from javascript?
I know that is standard to use private key on both sides, but javascript is public, so this is not very secure :)
I already checked this: Authorization and Authentication to REST API from JavaScript Client
and read lot of information on internet, but it seems to be impossible to authenticate from javascript (code is visible)
Thanks a lot!
Yes, you can but there are some things to be aware of. Once the user of your JS application is authenticated, you can store them within the local storage. Then you can use them within your request. Be careful of possible XSS attacks.
Here are some links that can help you:
https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
Securing a API consumed by AJAX
Hope it helps you,
Thierry
As you mention, storing confidential credentials in the browser is a bad idea (due to XSS vulnerabilities). HTTPS-Only cookies are the most secure way to store an authentication token on the client (to minimize XSS attacks) but you'll need to setup a CSRF prevention strategy as well.
Here's an article I've written that discusses the details in greater depth:
Token Based Authentication for Single Page Apps
Disclaimer: I work at Stormpath