2

I would like to know if publishing _id of a document is safe.

I am using an analytics software to track behaviors of users, and I need to access _id on client for better context. However, it vexes me that I am publishing an internal information of a document.

All in all, being new to mongo and Meteor, I would like to make sure if this is safe. Any suggestions?

mc9
  • 6,121
  • 13
  • 49
  • 87
  • [**This**](http://security.stackexchange.com/questions/63687/) and [**that**](http://stackoverflow.com/questions/4587523/) may be useful info for you. – chridam Jun 26 '15 at 06:39

4 Answers4

3

If the document's _id is created using Meteor the document's _id is at best fully random.

It doesn't contain any information besides a reference to the document itself.

If you're publishing the document this should no reveal any further information.

Even when Meteor uses an ObjectID (Meteor generated) the timestamp and other identifiers are random too. The timestamp component is also random, as mentioned in the Meteor docs (http://docs.meteor.com/#/full/mongo_object_id)

If an _id is used that is an ObjectId generated by MongoDB externally, outside of Meteor contains information such as a timestamp and details about your server. But this should not be an issue if your app is a typical Meteor app.

Tarang
  • 75,157
  • 39
  • 215
  • 276
  • This is crazy! Now _id order doesn't correspond to insertion order! And we need to have a separate created_at field with index! Why would they do this to us? – Sergio Tulentsev Jun 26 '15 at 09:56
  • @SergioTulentsev Given Meteor's design there's actually now way to guarantee insertion order. The _id is generated on the client and there may be a latency disparity or a temporary internet issue so the order will always end up being wrong. This is the reason Meteor uses temporary values. An alternative is to use your own _id system by inserting them on the server side. Losing latency compensation – Tarang Jun 26 '15 at 11:15
  • @SergioTulentsev correction: no* way to guarantee insertion order. – Tarang Jun 26 '15 at 11:23
  • @SergioTulentsev remember that _id does not correspond to insertion order anyway, you can get a lower _id inserted after a higher _id (I saw this when sorting by _id but showing a date field :\, plus it is in the docs) but yes, this is kinda odd, the _id index has no solid order anymore – Sammaye Jun 26 '15 at 11:28
  • @Sammaye: if you generate ids on client - yes. But _id order should correspond to insertion order if you leave the generation to the mongod. – Sergio Tulentsev Jun 26 '15 at 11:30
  • @SergioTulentsev It is not possible to leave id generation to mongod with Meteor. If you do not provide an _id Meteor will generate a random one. You can only manually create your own _ids on the server side. – Tarang Jun 26 '15 at 11:53
  • @Akshat: yeah, I meant, in general. With other languages/clients. – Sergio Tulentsev Jun 26 '15 at 11:53
  • @Sammaye What i meant was you can insert the _ids with the correct order, but there's no guarantee they will be entered in the server this way. Theere's a very high chance the order will be changed/incorrect by the time its inserted – Tarang Jun 26 '15 at 11:53
  • @Akshat well one of the things that gives the _id it's ordered range is the monotonical time part, if this is now random (as the meteor docs state, I checked when I wrote my first comment I deleted) then it loses it's order – Sammaye Jun 26 '15 at 12:02
1

If you're using the default ObjectId implementation, here's what you'd be exposing:

ObjectId is a 12-byte BSON type, constructed using:

  • a 4-byte value representing the seconds since the Unix epoch,
  • a 3-byte machine identifier,
  • a 2-byte process id, and
  • a 3-byte counter, starting with a random value.

There are some slight concerns here:

  • Knowing the time, machine ID, process ID and a previous counter lets an attacker plausibly guess other ObjectIds which might be used to obtain other rows from your database (if you enable any form of access via the ID, which seems possible given that you want the client to know the _id).
  • Knowing the machine identifier might allow an attacker to identify particular database servers (only relevant if they already have access to your network)
  • Knowing the PID might allow an attacker to figure out the uptime of your DB server (watching for when the PID changes)
  • Knowing the time gives the attacker the creation time of the document (only valuable if the attacker didn't already know that)

These are all fairly minor leaks in the grand scheme of things, although I usually lean towards avoiding unnecessary information leakage where possible. Consider using a non-default _id column (e.g. using a randomly-generated value), and whether you really need the plaintext _id column to be visible (maybe you can use a cryptographic hash of it instead, or perhaps you can encrypt it so that the client only sees an encrypted version).

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • In a distributed network of other mongods 1-3 would be very difficult, single server 1 might be possible but still with how granular the time is you would spend a lot of time guessing the distance between objectids – Sammaye Jun 26 '15 at 08:27
  • * providing the PID has not changed etc etc – Sammaye Jun 26 '15 at 08:58
  • Going against the flow (using custom random IDs or exposing hashed/encrypted ids) is more of a stunt/hassle than a real security measure. At best, it will only make your code more complicated. At worst, it'll introduce bugs (if your random ids are less random and produce clashes, or something) – Sergio Tulentsev Jun 26 '15 at 09:47
0

It's quite safe. As other answers correctly stated, yes, it may contain some bits of information about your machine and server process (depending on where the id was generated, in meteor or mongodb server)

But to leverage them for any malicious actions is a tough task. An attacker pretty much needs to get inside your network to do anything. And if he's in your network, you're screwed anyway, regardless of what ID format you expose.

By any measure, ObjectId is more resilient to guesses than a regular auto-incrementing integer ids you find in other databases. And they're exposed all the time!

Note, though, that you shouldn't rely on the fact that an id is hard to guess. Protect private pages with authorization checks, etc. So that even if an attacker correctly guesses an id of a page he shouldn't have access to, he is refused the access.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
-1

Exposing document reference(_id is not only data , it is an reference, primary key) is not at all safe.

_id is 12 bytes which consist of

  1. 4 byte - timestamp
  2. 3 byte - machine id
  3. 2 byte - process id
  4. 3 byte - increment counter

There are possible way to find out all the details about document and collection of the database using _id.

Note: Exposing _id is not at all safe.

Scenario

Suppose your are using _id for some socket listener or emitter, Anyone can guess other _id using that particular exposed _id and emit some malicious data.

When you expose _id, It contains timestamp, so you are exposing the time of creation of that particular data.

Community
  • 1
  • 1
karthick
  • 5,998
  • 12
  • 52
  • 90