I'm new to Node, Passport and authentication in web development in general
I followed this tutorial for setting up local authentication using the Passport module.
I was hoping an experienced developer could comment on the security of the design being taught there.
More specifically,
1) When the author does a POST for sending credentials, shouldn't he be doing it over HTTPS? When is it necessary to use HTTPS so that others aren't sniffing your information? How could the design be changed to POST using HTTPS?
2) I can't follow how session is being kept track of. Does passport abstract all of the session work? If so, are they using cookies? Are the cookies plaintext? Does the user get a token back in a cookie? Is that how isLoggedIn() works?
3) Is he getting any protection from content injection for free? I don't see any code to try and escape dangerous characters or anything.
Anyway, how hacker safe is this design?
Related
I am trying to build a registration/login system using the PERN stack (Postgres, Express, React & Node) for a client website.
I was doing some researching and came across HTTP Cookie and JWT token authorizations (many more but apparently those two are the dominant).
I noticed alot apps and tutorials that uses Node JS seems to use JWT alot, and store these in localstorage. But I'm doubtful about the security because I feel like a developer can basically go into localstorage and get the JWT token which o
Is there a better way to secure user authentications with this stack or is using localstorage the rule of thumb? If so, why is that?
Thank you for your time.
One limiting medium to the security of both session IDs and JWTs is network transmission. In this case, both are only as secure as the network itself. But most likely, your application would be using something like HTTPS or SSL, in which case any data being sent across the network would be reasonably secure.
Regarding your other edge case of someone trying to sniff at a JWT in local storage, there are a few options you may consider:
First, the nature of the JWT is that it is generally tamper-proof. A JWT contains inside of it a checksum, which is a unique hash based on the actual contents of the JWT. Let's says that some malicious user sniffed local storage, and then tried to change e.g. the claims section of the JWT. In doing so, this would also change the checksum (which that user would not be able to figure out, lacking the server key). Then, the next time the compromised JWT is sent to the server, the server would reject it, because the computed checksum would not match with the value contained in the JWT.
Second, in the event the above be deemed not secure enough, it is possible to pass around encrypted JWT. If you go with this option, both the server and client would encrypt/decrypt before sending a JWT, which adds an extra layer of protection.
Security of network transmission is just one case of whole solution in web applications.
Im currently in the research of the same topic and as you said a lot of tutorials, blogs, youtube and other sources gives an excellent examples of using JWT tokens for handling user data. Unfortunately hardly anyone go deepest in handling and processing user sessions from administration point of view - where the real problems starts.
Logging the user in and sends JTW token in response to the client is not a problem at all. The problem begin when you as administrator want to invalidate a user.
Refer to this sources:
http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
Logout/invalidate a JWT
The session cookie with session data stored in server-side is currently the best option for web application.
Just have some general questions about the level of security one can expect when using passport for an App's Authentication;
I am currently in the process of designing my first App using a MongoDB, Express, React and Node.js stack. Without having much prior knowledge about cyber security I have done quite a bit of research about authentication and what type of attacks can occur on my site. I have opted to use a cookie-based authentication system with the passport.js npm package and I have designed my /login route to require that the user's password and username first pass a passport.authenticate('local', ....) middleware setup before a session and cookie are created.
In order to persist the current user in my react app, I have a function which requests the server to provide it with the currently active passport session if there is one - and this seems to work as it will not maintain a login state if the user deletes the session cookie from their browser.
I am a bit skeptical of passport and I'm curious to know how easily it could be breached by someone who has a higher understanding of how it works, so the things I am wondering are several:
Is this type of authentication setup secure?
Are there any additional requirements that one must implement in order for passport to be a
legitimate method of authentication for an App?
Is using passport to authenticate users considered to be bad practice? Would showcasing an app that
authenticates users by using an npm package look bad if I were to showcase this application to a
potential employer?
I can share code if necessary to better illustrate my code setup, although I would prefer not to if at all possible. Any advice would be much appreciated, thanks!
TLDR:
Is passport.js a secure method to authenticate users? Is using passport.js for this bad practice?
Passport.js provides authentication, not security. It is fairly easy to misconfigure by following online tutorials, so take care - the tool is only as good as the hand it is in. To add security to passport, you will need at the very least three additional elements:
Strong state model for the session (or token) that does not leak private fields and uses argon2 for password hashing.
No mistakes on the front-end with CSRF or XSS.
Rate and buffer limitters on Node itself or, even better, on your reverse proxy.
I'm writing my first Express NodeJS app and I want to know what is the best practice when it comes to authentication middlewares?
I'm using access tokens and cookies (which are composed from user id and some random bytes) for each new user, and for some routes I want only given users to have access to it.
Is a good idea to access database from a middleware? Or where should I check if a given user has access to a given resource?
Thank you!
There are many modules built for authentication purpose for nodejs applications. However, the most commonly used module for nodejs/expressjs is Passport. If you wish to stay isolated from such libraries, nodejs has built-in libraries for encryption etc, for example, check this out.
For sessions and cookies, using signed cookies is always a good practice. Check out this SO post. There are many good practices for maintaining security (say, using https over http, token based authentication, etc.) followed throughout the development grounds, which you'll learn as you go on. Here is a short tutorial of JWT(JSON Web Tokens) for a good introduction to token based authentication in JSON you can check out.
Happy coding :)
i have implemented the tokken based authentication in my project instead of the cookie-session based authentication. So, in jwt(jason-web-tokkens), every time is send req to server,I in headers attach the tokken and send it to server which validate it against the secret is used in generation the tokkkne in the first time and send me the response. Now, i have concern about it, first the tokken is saved in the local storage in browser.although the tokken is hashed but what if the hacker just take that tokken from storage and use it?
can anyone tell me how it stop the CORS attack?
I'm confused and cannot find any reliable answer online.
By CORS I think you are referring to XSS attacks? If so, the best way to prevent XSS is to secure your app against untrusted input. That is easier said than done, here is some information on that:
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
The easier way to prevent XSS is to store the token in a Secure, HTTP only cookie. This means that the Javascript environment cannot touch it, and it will only be sent over secure channels.
Nothing comes for free though :) If you put the token in a cookie, you will also need to setup a CSRF prevention strategy:
https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet
This can be a lot to take in!
I work at Stormpath and I recently wrote this blog post that covers these topics: Token Based Authentication for Single Page Apps (SPAs)
For a project I’m working on currently I am developing an API using Node/Express/Mongo and separately developing a website using the same tools. Ideally I want to host these on separate servers so they can be scaled as required.
For authentication I am using jsonwebtoken which I’ve set up and I’m generally pleased with how it’s working.
BUT…
On the website I want to be able to restrict (using Express) certain routes to authenticated users and I’m struggling a little with the best way to implement this. The token is currently being saved in LocalStorage.
I think I could pass the token through a get parameter to any routes I want to protect and then check this token on the website server (obviously this means including the jwt secret here too but I don’t see a huge problem with that).
So my questions are
Would this work?
Would it mean (no pun intended) I end up with ugly URLs
Would I just be better hosting both on the same server as I could then save the generated token on the server side?
Is there a better solution?
I should say I don’t want to use Angular - I’m aware this would solve some of my problems but it would create more for me!
First off, I'll answer your questions directly:
Will this work? Yes, it will work. But there are many downsides (see below for more discussion).
Not necessarily. I don't really consider ugly urls to include the querystring. But regardless, all authentication information (tokens, etc.) should be included in the HTTP Authorization HEADER itself -- and never in the URL (or querystring).
This doesn't matter so much in your case, because as long as your JWT-generating code has the same secret key that your web server does, you can verify the token's authenticity.
Yes! Read below.
So, now that we got those questions out of the way, let me explain why the approach you're taking isn't the best idea currently (you're not too far off from a good solution though!):
Firstly, storing any authentication tokens in Local Storage is a bad idea currently, because of XSS (Cross Site Scripting attacks). Local Storage doesn't offer any form of domain limitation, so your users can be tricked into giving their tokens up quite easily.
Here's a good article which explains more about why this is a bad idea in easy-to-understand form: http://michael-coates.blogspot.com/2010/07/html5-local-storage-and-xss.html
What you should be doing instead: storing your JWT in a client-side cookie that is signed and encrypted. In the Node world, there's an excellent mozilla session library which handles this for you automatically: https://github.com/mozilla/node-client-sessions
Next up, you never want to pass authentication tokens (JWTs) via querystrings. There are several reasons why:
Most web servers will log all URL requests (including querystrings), meaning that if anyone gets a hold of these logs they can authenticate as your users.
Users see this information in the querystring, and it looks ugly.
Instead, you should be using the HTTP Authorization header (it's a standard), to supply your credentials to the server. This has numerous benefits:
This information is not typically logged by web servers (no messy audit trail).
This information can be parsed by lots of standard libraries.
This information is not seen by end-users casually browsing a site, and doesn't affect your URL patterns.
Assuming you're using OAuth 2 bearer tokens, you might craft your HTTP Authorization header as follows (assuming you're representing it as a JSON blob):
{"Authorization": "Bearer myaccesstokenhere"}
Now, lastly, if you're looking for a good implementation of the above practices, I actually wrote and maintain one of the more popular auth libraries in Node: stormpath-express.
It handles all of the use cases above in a clean, well audited way, and also provides some convenient middlewares for handling authentication automatically.
Here's a link to the middleware implementations (you might find these concepts useful): https://github.com/stormpath/stormpath-express/blob/master/lib/authentication.js
The apiAuthenticationRequired middleware, itself, is pretty nice, as it will reject a user's request if they're not authenticating properly via API authentication (either HTTP Basic Auth or OAuth2 with Bearer tokens + JWTs).
Hopefully this helps!