I have a client-side react app that I need to fetch information from a MongoDB Atlas collection that is being populated directly to the source by another individual. When I went to check out the connection string I noticed that the user password for db access would need to be present in the code:
(Not enough rep to post images sorry)
https://i.imgur.com/5Vs23WJ.png
Now obviously if I include this right in my front-end code anybody will be able to see my password and that's no good. But I need this app to be self-contained and I don't want to have to host a server just to reroute the single Get request that is called upon loading the site.
If I create a new user with read-only privileges, is it safe to keep that user's (super generic obviously) password in the front-end code for access to the db? Is there any harm in this? Am I correct in assuming that non-whitelisted IP addresses aren't able to make requests to the Atlas db? The only address that is going to be whitelisted is the IP where the web-app will be hosted, so I'd imagine I don't need to worry about someone spamming requests to rack up charges on my Atlas account or doing anything else malicious?
I'm a recent grad so I don't have much experience with secure deployment but I'm hoping I can change that this summer.
Thanks :)
I'm not sure about "best" practices, but I'll try to answer according to what I would do:
is it safe to keep that user's (super generic obviously) password in the front-end code for access to the db?
Yes you can create a read-only user. It's generally not a good idea to use a super-user to do your reads. I would only give as much access as the job requires.
Am I correct in assuming that non-whitelisted IP addresses aren't able to make requests to the Atlas db?
Correct. Only whitelisted IPs will be able to connect to the Atlas instance.
Having answered that, I personally would either:
create an API layer on top of the database to prevent direct access to the database by a client application, or
(If applicable) create a Stitch Webhook that provides a Stitch-based REST API layer on top of the Atlas deployment.
The idea is to provide security by limiting access to the database from the outside world. Using a whitelist is one layer of security. Using a REST API is further security layer that essentially forces anything that needs database access to go through a guarded gate that is under your control.
Some additional benefits of a REST API gateway:
Should your Atlas URI changes in the future, you don't need to redeploy the client applications everywhere again. You just reconfigure the REST API gateway to point to the new Atlas URI, while your client application can still use the existing REST API address with no change.
Limiting client connections to the database itself. Since only your API gateway can connect directly to the database, there is little chance that the database can get accidentally DDOSed when you have a lot of clients active at the same time.
Note that I would not consider the above to be "best" practice by any means. It's just how I would do it.
Related
I'm running MongoDB with authorisation enabled, and multiple users created.
Now I want the clients to be able to connect anonymously as well, and be able to perform selected actions on the database without authenticating.
Is it possible to configure Mongo to have the unauthenticated access enabled at the same time as authenticated, and to control what the unauthenticated user can do?
To allow limited permission for an anonymous client can prove to be detrimental to your application. You can never predict the behaviour of client, there is always going to be some degree of uncertainity regarding it.This makes your application vulnerable to malicious exploitation.
The ideal way would be to let your application code talk to the database with a limited set of permissions(eg.read only, targetting specific database). You can expose a few api's that does what is required for anonymous clients.
We're starting to migrate our Website to a REST Service based system and are in the process of developing the core right now.
In our current setup a user has one or more "accounts" assigned which define what data he can see on the website. Only one account can be active for a given user at any time. Right now we store the selected account in the database and use it to filter all queries.
Now I'm not sure how to handle this properly in a REST environment. Possible solutions I found are:
Sending the requested account with every request
Storing the current account in the auth token. (We're using JWT for that)
Having the current account stored on the server and calling a specific resource to change it
Each of these has its pros and cons for our setup. Currently we're using the 3rd approach in our Website. But what would be the correct way to handle such a thing in a REST environment?
Yea the design you are dealing with is fairly bad, and what you really want to do is remove the state completely out of this system.
For that reason the first option is by far superior:
Sending the requested account with every request
If this is simply an id, there's a very simple way to do this, just prefix all your (relevant) routes / uris with this account id. For example:
http://api.example.org/accounts/{id}/...
This way the 'state' is maintained by virtue of which url you are accessing, and the server can be unaware of the state.
I'm getting into the world of fullstack development and I'm trying to develop app which front is completely separated from backend (front is being served from node server and backend is java).
Now, the issue - how should I get about securing my app?
I'd like to have many fronts and many backend instances connected through load balancers and I'd like to keep all the state on client, so I can without any issue switch to another backend server and continue as nothing happened.
Currently I'm using OAuth2 tokens but I'm concerned about security and stealing the tokens, which are completely stored in cookie on user side. Also, The app (obviously) stores those tokens somewhere, so another instance of my backend app wouldn't accept the token. In best case scenario I can implement some mechanism that would automatically request a new one and in worst case I'd have to login again. I don't want that to happen.
Also, here I have a problem with social auth. Allright, I'm receiving token from Google on front, but giving it to backend and creating a user there is major pain, I have to write a lot of code manually to create such user and save it.
And again, I'm not certain about security level of this solution.
So the question is basically - currently, what is the best way to secure an app which should have completely separate front and backend, which would have no issue with switch backend server between requests?
As regards tokens being stolen from the Client: you can't do anything about this. It is up to the client to protect themselves. What I mean is, if you need a username and password to access a service, and the Client is infected with a key-logger, and a hacker steals those credentials, there is nothing you can do on the server side to protect against this.
As regards your idea of multiple back-ends, this is a common feature of any system with multiple application servers. For example, if you have multiple web servers and want any request to be routable to any server. For this, you need a central database which stores any information which needs to be shared. It's slower, obviously, but much more resilient.
i know this is a question that has been asked many time. but im still concerned about best practice when trying to develop secure code in meteor.
i know you can prevent the client from being able to access the database with the command:
meteor remove insecure
my code currently adds, retrieves records by using Meteor.methods() so although the client is not able to insert data into a collection, it can use the Meteor.method() function. im concerned about holding the login details in the database because would this not mean that the client can use the Meteor.method() function to add/get/remove data from the database.
the client being able to call the Meteor.methods() function seems to still keep the same risk doesn't it? or have i coded me work wrong?
if it help, here is a run down of what my work is doing:
application loads
client calls to get username and password from database
client sends login details to external server (over https) to initiate socket.io connection.
step 2 is the risk because it seems to allow the client to get the login details. once it has this, it uses the socket.io.js library and the api to my webservice to login. so meteor remove insecure doesnt seem to have secured it because get methods are still available in the Meteor.methods()?
being able to use these functions are quite crucial to retrieving data from the database, is there a way around this? what would be best practice for communicating to the database without exposing private data to the client?
Meteor's insecure package is just a tool provided by MDG to quickly prototype apps. It is not meant to be runned in a production app and some people think is a best practise to remove it all together from the start.
After you remove this package, if you want to interact with the database on the client using mini-mongo you must create the appropiate allow and deny rules on the collection. Here is the link for the Meteor documentation on this topic. The other way to interact with the database, is as you said, using Meteor.methods().
Meteor methods calls don't trigger allow or deny rules, since they are runned on the server. You must hardwire all the security measures you need on the Meteor Call by yourself. So it can be a security problem if you don't take the time to secure the call.
Regarding authenticating your clients I would suggest you take a look at Meteor's Accounts package. For example you can add this two packages for basic username/password authentication:
meteor add accounts-base accounts-passwords
Then you can just use the methods detailed on the Meteor Documentation.
I hope this helps.
Login
If you are using accounts-password, you can check the source here to see details of how it works. But here's a rough overview of it. When you call Meteor.loginWithPassword, the password is hashed client-side. Then a method is called with the parameters. The password is then salted and checked against the database server-side. If it matches, the client gets logged in. The client then subscribes to their own user data (Meteor.user()). The server only publishes their data. So everyone else's data is save.
Methods
A method executes code server-side. So they are generally secure. But you can of course write insecure methods. Just know, that you can't trust the parameters passed by the user.
I have tried Google with queries similar to the title of this question, but haven't found anything useful.
Background: I am building a web app and would like to add a user authentication level to it. I cannot imagine anything worse than building a user authentication system from the ground up, so I want a quick solution.
I'm looking for open source software I can host on my server that provides an auth layer I can connect to, with multiple user accounts
Criteria:
I want to host the software on my own server
Provide a log in screen that works with multiple sign in strategies - twitter, facebook, vanilla email, etc.
Persists users to a database (preferably postgres) and persists session data
Preferably lets me store a minimal amount of data per user, like key value store
Has a client-side (Javascript) API, like Facebook's JS, so I can use this auth service on multiple sites. Namely, I want to use it on localhost or my own file system (when allowing file cookies). Client side JS API exposes methods like log in / log out
Has a server side API (such as exposes local RESTful endpoints) so that when I do build out my server side app for other data storage outside of the user, my app can query the auth service for log in status.
I want to run this stack completely independently of my own app - in fact I want to run this auth service and purely communicate to it from my local dev environment without building any server side app of my own.
I have used Firebase and they do many of the things that I want, including log in strategies and the client / server side APIs, but I want to be able to host my own version of this.
I can't imagine anyone takes pleasure out of building user authentication of any kind, so I'm surprised I haven't found anything in research.
I also know this is an open-ended question, but as far as I can tell I haven't found anything satisfying my requirements.
I like Devise (https://github.com/plataformatec/devise), which is for Rails. It has an active community with a boatloads of plugins available that can fulfill many of your requirements.
I didn't see a language specified; most languages and frameworks have their own implementations. Can you provide more information?
Example: I use the Flask framework on python. In addition, I use the Authomatic library which provides Oauth access for twitter, google, facebook, etc.
What I was looking for is something called a Single Sign On solution. According to this list there is nothing currently that meets my criteria.
Instead I have chosen to just run a local webserver and implement a regular auth flow.