How to clean SSJS in Domino server after someone u

2019-02-06 11:52发布

问题:

How to clean SSJS (Server Side Javascript) in Domino server after someone used javascript prototype in a nsf?

Mark Roden discovered a huge weakness in XPages SSJS: (thanks to David Leedy for tell me about this and show me the article).

If you have the following SSJS code:

var dummyObj = {}
dummyObj.prototype.NAME = "Johann"

XPages SSJS doesn't care that you uses var (var means the variable must be local) and it makes dummyObj.NAME visible in the whole server with the value Johann. So if another nsf in the same server uses a var with the same name it inherits the whole prototype:

var dummyObj = {}
println(dummyObj.NAME) /*prints "Johann" */ 

This is a huge bug (one that makes unreliable XPages SSJS IMO). Even if you don't use prototype at all, if someone else in his application do something like this:

String.prototype.split = function(){ return "I broke this method" }

It will broke all applications in the same server that uses the innocent split().

So, the question is: if someone "by mistake" writes the following SSJS (XPages Server Side Javascript) in a NSF:

String.prototype.split = function(){ return "I broke this method" }

How can I fix String.prototype.split() to his original value?

As Mark Roden said, restarting HTTP task doesn't fix it.

///////////////////////////////////////////////////////////

Edit 1: Why I think this is a huge bug:

I'm a Javascript fan but IMHO @MarkyRoden has discovered a huge bug in SSJS. Shims and polyfills aren't really the main problem. Eval is known to be a bad practice but the prototype object is a fundamental element of basic Javascript. It's the standard and preferred way to add methods to Javascript classes, it's also needed for inheritance and all kind of OOP stuff. So you will need some kind of namespace at server level in order to avoid collisions. All this is really bad but the huge problem is that just a line of code in one application can broke all applications in a server. Yes, you can trust in your developers but one of them can write a bad line by mistake and also a Domino server can have hundreds of applications from different software vendors. Set the responsability in code reviews is not a reliable enought procedure. Maybe it's time to have a real javascript engine in SSJS, like V8, Spidermonkey, Chakra or Rhino. As a workaround, I'm thinking in something like Tommy Valand's idea with Rhino in SSJS.

Edit 2: It's even worse. You can do things like:

prototype.importPackage = null

or

prototype.Array = null

As you can see in @SvenHasselbach's article: http://hasselba.ch/blog/?p=1371

Edit 3: IBM: you told me I could use SSJS. COME ONE! PLEASE FIX THIS, it's AWFUL. Please let's officially report this issue to IBM.

回答1:

You can reset the SSJS interpreter with the following Java code:

FacesContextExImpl fc = (FacesContextExImpl) FacesContextExImpl.getCurrentInstance();
UIViewRootEx2 uiRoot = (UIViewRootEx2) fc.getViewRoot();
JSContext jsContext = uiRoot.getJSInterpreter().getJSContext();
jsContext.getRegistry().init(jsContext);

This reinitializes the registry and all prototype functions.

EDIT: Changed the declaration of fc to the correct type.

EDIT 2: Here is the SSJS version:

var uiRoot = facesContext.getViewRoot();
var jsContext = uiRoot.getJSInterpreter().getJSContext();
var reg = jsContext.getRegistry();
reg.init( jsContext );

Does I understand you correctly, that you want to clean up the SSJS interpreter to avoid a collision with your own prototype extension? Just to clarify the answer above: This reinitializes the SSJS interpreter once. And only once. You have to do this over and over again, because directly after reinitializing, another application on the server can overwrite the prototype functionality again. That's why this is not a real solution, it is an answer to your initial question.

It will have interessting consequences if another application will do the same while your code tries to use your extension...



回答2:

try to do a Restart Task Http instead tell http restart will not do a full restart of the http task