8

In the following link https://docs.mongodb.com/manual/reference/bson-types/ It mentions JavaScript with Scope is a possible data type in documents.

My questions are:

(1) What is a JaveScript with scope?

(2) Is it some kind of "Internal" data types in MongoDB

By “internal”, I mean it cannot be used by users. I didn't find any more info about this type, except it is mentioned in above link

(3) In mongo c driver, I found Struct bson_value_t http://mongoc.org/libbson/1.0.0/bson_value_t.html what is the "scope_data" buffer ?

Chang Su
  • 81
  • 2
  • Possible duplicate of [What is the use of type javascript/javascriptwithscope of bson](http://stackoverflow.com/questions/37941368/what-is-the-use-of-type-javascript-javascriptwithscope-of-bson) – Evan Trimboli Aug 25 '16 at 21:59
  • 4
    @EvanTrimboli I found that when looking for duplicates also. The answer isn't helpful at all. – 4castle Aug 25 '16 at 22:01

1 Answers1

10

Believe it or not, it's possible to store a "live" Javascript function in a MongoDB collection:

> db.collection.insert({ name: "add1", f: (function(x) { return x + 1 }) })
WriteResult({ "nInserted" : 1 })
> db.collection.findOne({ name: "add1" }).f(123)
124

A "function with closure" (or, more simply, a "closure") is a function which refers to variables which exist outside the function, like incrementX in the following snippet:

var x = 1;
function incrementX() { x++; }

These functions can be stored in a MongoDB collection as well; they will bind to the scope of the mongo session when they're executed:

> db.collection.insert({
    name: "incrementX",
    f: (function() { x++; })
})
WriteResult({ "nInserted" : 1 })
> var x = 123;
> db.collection.findOne({ name: "incrementX" }).f()
> x
124

For some unknowable reason, the BSON designers decided to use a different data type for Javascript functions depending on whether they were closed over any variables or not. The plain "Javascript" type is used for functions which don't close over any variables, and "Javascript (with scope)" is used for closures.


Why one would store a Javascript function in a MongoDB collection is… a good question. I'm not sure what the purpose of this feature is; it honestly seems rather dangerous and ill-advised to me. In particular, it'll be difficult to do anything useful with them if you're using a Mongo driver in a non-Javascript language, and using functions in the database exposes you to potential exploits if a malicious user is able to inject a function into your database. If I were you, I'd pretend this feature didn't exist and move on.

  • I thought the same, but if you try and query for that incrementX doc using `{f: {$type: 15}}` (JS with scope) it won't find it, but `{f: {$type: 13}}` (JS) will. – JohnnyHK Aug 26 '16 at 00:34
  • That re-scoping of closures to the current context seems even more scary. – Bergi Aug 26 '16 at 00:41
  • @Bergi Indeed. I'd be particularly concerned what might happen if a function overwrote global variables like `db`… –  Aug 26 '16 at 00:45
  • @JohnnyHK Hmm, weird. Maybe "with closure" is used specifically for functions which close over something other than the global scope? Let me experiment a bit. –  Aug 26 '16 at 00:49
  • 3
    @duskwuff oh no, did your experiments go awry? Did your computer explode? Tell me! What happens? – kdojeteri Dec 06 '17 at 16:27
  • Storing and using the stored code is only as scary as giving public access to your database. If your database is being access from the localhost and it only stores what you put in it then its not scary at all. But the question is whats the difference between this javascript type and just storing a string and using eval to execute it? – Nick Sotiros Apr 08 '19 at 03:25