3

For instance, I have a library and I would like to protect the source code to being viewed. The first method that comes to mind is to create public wrappers for private functions like the following

function executeMyCoolFunction(param1, param2, param3) {
  return executeMyCoolFunction_(param1, param2, param3);
}

Only public part of the code will be visible in this way. It is fine, but all Google Service functions look like function abs() {/* */}. I am curious, is there an approach to hide library source code like Google does?

Edit 00: Do not "hide" a library code by using another library, i.e. the LibA with known project key uses the LibB with unknown project key. The public functions code of LibB is possible to get and even execute them. The code is

function exploreLib_(lib, libName) {
  if (libName == null) {
    for (var name in this) {
      if (this[name] == lib) {
        libName = name;
      }
    }
  }
  var res = [];
  for (var entity in lib) {
    var obj = lib[entity];
    var code;
    if (obj["toSource"] != null) {
      code = obj.toSource();
    }
    else if (obj["toString"] != null) {
      code = obj.toString();
    }
    else {
      var nextLibCode = exploreLib_(obj, libName + "." + entity);
      res = res.concat(nextLibCode);
    }
    if (code != null) {
      res.push({ libraryName: libName, functionCode: code });
    }
  }
  return res;
}

function explorerLibPublicFunctionsCode() {
  var lstPublicFunctions = exploreLib_(LibA);
  var password = LibA.LibB.getPassword();
}
megabyte1024
  • 8,482
  • 4
  • 30
  • 44

2 Answers2

0

Edit: changed my answer to reflect the fact that an exception's stacktrace will contain the library project key.

In this example, MyLibraryB is a library included by MyLibraryA. Both are shared publicly to view (access controls) but only MyLibraryA's project key is made known. It appears it would be very difficult for an attacker to see the code in MyLibraryB:

//this function is in your MyLibraryA, and you share its project key
function executeMyCoolFunction(param1, param2, param3) {
  for (var i = 0; i < 1000000; i++) {
    debugger; //forces a breakpoint that the IDE cannot? step over
  }
  //... your code goes here
  //don't share MyLibraryB project key
  MyLibraryB.doSomething(args...); 
}

but as per the @megabyte1024's comments, if you were to cause an exception in MyLibraryB.doSomething(), the stacktrace would contain the project key to MyLibraryB.

Peter
  • 5,501
  • 2
  • 26
  • 42
  • In my original post I wrote about public libraries (the project key is known), which developers publish to everyone, like the [Notable Script Libraries](https://developers.google.com/apps-script/notable-script-libraries). If the project key is known it is possible to view the public functions code. – megabyte1024 Aug 12 '12 at 07:48
  • 1
    It is possible to get the project ID of the the `MyLibraryB`, if the make the code, which uses the `MyLibraryA` to throw an exception in the `MyLibraryB`. If the exception code is something like `throw new Error('blah-blah-blah')`, then the caught exception will contain the complete stack and the exception project ID. – megabyte1024 Aug 12 '12 at 11:03
  • Playing a little bit with the library scripts, I found a way to get public functions code of `MyLibraryB` without knowing its project ID. It is quite simple. – megabyte1024 Aug 12 '12 at 17:31
  • Peter, the statement `It appears it would be very difficult for an attacker to see the code in MyLibraryB` is not correct. As I wrote, in my previous comment, is pretty easy to get the MyLibraryB code. Please see the `Edit 00` paragraph of my question. – megabyte1024 Aug 15 '12 at 08:14
  • I agree, hence the phrase after the code ... "but as per @metabyte's comments...". – Peter Aug 15 '12 at 12:08
  • It is possible to retrieve the LibB code even without the stack trace and the LibB project key. – megabyte1024 Aug 15 '12 at 12:36
  • Yes I didn't miss that comment and I'm sure you're correct :) It's up to you if and when you disclose the "how". I think the point we've arrived at is that a developer can't consider libraries as a security mechanism for code - libraries are as secure as the google drive acls applied to them. – Peter Aug 15 '12 at 20:58
0

I don't know what google does, but you could do something like this (not tested! just an idea):

function declarations:

var myApp = {
  foo: function { /**/ },
  bar: function { /**/ }
};

and then, in another place, an anonymous function writes foo() and bar():

(function(a) {
  a['\u0066\u006F\u006F'] = function(){
    // here code for foo
  };
  a['\u0062\u0061\u0072'] = function(){
    // here code for bar
  };
})(myApp);

You can pack or minify to obfuscate even more.

Peter
  • 5,138
  • 5
  • 29
  • 38
  • No luck. I tried the following code - `(function(inst) { inst.test3 = function() { return 3; } inst['test4'] = function() { return 4; } }(this)); function test3() { /**/ } function test4() { /**/ }`, but "the" real functions code, in any case, is visible in calling code. – megabyte1024 Aug 12 '12 at 16:11
  • You can obfuscate, but your code is going to be always visible. The browser needs to see it. – Peter Aug 12 '12 at 18:59
  • 3
    Browsers do not need to see any Google Apps Script (except JavaScript code in HTML templates) because the GASes are executed on the Google servers and not on clients (Browsers). Google hides its own scripts, and there is a workaround by using the private functions. – megabyte1024 Aug 12 '12 at 19:11