Security concern with cfs:gridfs


#1

The Atmosphere page for cfs:gridfs suggests defining a GridFS collection like this :

var imageStore = new FS.Store.GridFS("images", {
  mongoUrl: 'mongodb://127.0.0.1:27017/test/', // optional, defaults to Meteor's local MongoDB
  maxTries: 1, // optional, default 5
      :  
      :  
});

Meanwhile the docs for Collections says :

To allow both client code and server code to access the same collection using the same API, it’s usually best to declare collections as global variables in a JavaScript file that’s present on both client and server.

I am concerned that when I do that, and put a breakpoint in the browser developer console, I can see the URL and port number of my database :

v Scope Variables 
  v Local 
    v this
      v primaryStore
        v mongoUrl: "mongodb://127.0.0.1:27017/test"

I’m not a security expert at all, but this does seem like a bad idea.

I built Meteor with meteor build --debug which makes it easy, of course, and I was unable to find it when I built my project minified, but I don’t have the knowledge or tools for it, either.

So I would like to ask :

  • is there a better way to define a GridFS collection that doesn’t risk exposing that information?

#2

So is the client supposed to connect to that remote mongo DB server? Or are you concerned because only the server is making that connection and the client should never see the IP & port?

If the client is going to connect to that remote server, then at some point anyone can see that connection request by monitoring their firewall. It doesn’t sound like the intention is to hide that IP & port.


#3

I understand it like this:

My NodeJS server connects to another server that has MongoDB. The client is supposed to use the small Mongo proxy that runs in the browser. Latency compensation needs to be able to communicate via DDP with the MongoDB client software running in NodeJS. It should not need to know anything about how the collection is instantiated on the server side.

I want to know if it is possible to define the collection only in server-side code, while also defining a client-side proxy that is ignorant of the server side details.

(I do understand that I could call Meteor methods as an alternative, but that would entail synch / asynch trickery I shouldn’t have to do.)


#4

I seem to have solved this one myself: Yay!

I move the MongoDB server specification out to my settings.json file like this :

{
    "public": {
        "APP_VERSION": "0.9.8.3"
    }
  , "MONGO_SERVER": "mongo"
  , "MONGO_PORT": 27017
         :  
         :  
}

I define the collection like this :

 console.log("Client visible   : " + Meteor.settings.public.APP_VERSION);
 console.log("Client INvisible : " + Meteor.settings.MONGO_SERVER);
 var MONGO_URL = 'mongodb://' + Meteor.settings.MONGO_SERVER 
              + ':' + Meteor.settings.MONGO_PORT 
              + '/' + Meteor.settings.MONGO_DB;
 var imageStore = new FS.Store.GridFS("images", {
    mongoUrl: MONGO_URL,

In the server terminal log I see :

Client visible   : 0.9.8.3
Client INvisible : mongo

In the browser console log I see :

Client visible   : 0.9.8.3
Client INvisible : undefined

When I track down the collection among the client variables I see :

v Scope Variables 
  v Local 
    v this
      v primaryStore
        v mongoUrl: "mongodb://undefined:undefined/undefined"

But, my app works just the same as before.


#5

This is exactly what I have done in the past, though I ended up doing this for another reason entirely. When declaring the client side collections, anything that seems like it is only necessary on the server side (such as file paths for filesystem) can be anything on the client and still be valid. This means you can keep sensitive information server-side only and just put garbage in that same spot on the client to make it work.


#6

Thanks for sharing. Nice trick. Could come handy one day.