Need advice on prototype pollution breaking (for example) Array.find(), causing issues with other nodes

Hi, I am updating a cron type node and using a new library that works perfectly outside of node-red but has (had) a serious bug when ran inside a custom node.

fore warning...
I had an old version of node-red-contrib-opcua installed globally that used an old shim lib called collections that changed the implementation of Array.find()

The issue...

  • An older install of node-red-contrib-opcua has a dependency on collections V^3.0.0
  • This library unconditionally defines Array.find() function that returns an index or -1
  • Normally Array.find() returns the 'found item' or undefined (see here)

Essentially, if I (or anyone) has an older version of node-red-contrib-opcua (or any other node that has bad shims) things like this bad implementation of Array.find() will cause bugs and other side-effects.

Questions

  • Is there some way of identifying a node.js prototype is overwritten (especially on things like the now standard Array)?
    • is this perhaps something node-red could/should do?
  • Is there a way to undo the overwritten find function? Revert it to original node.js implementation?
  • Is there another way to handle it - perhaps my own shim to ensure functionality?
1 Like

I reported the bug on that nasty piece of code. I believe that it uses Array.prototype.find which globally redefines the Array object for all code. It is utterly unnecessary of course & very dangerous. I reported it because someone reported a bug in uibuilder - of course, it wasn't in uibuilder (how could it be!!) but it did cause it to crash.

While I'm not a great JavaScript expert, I don't believe that JS has sufficient introspection capabilities to do this even with the latest versions of JS which, at least, are getting better at being able to introspect code.

I think that you would have to understand a reference model of JS in order to be able to pick up the differences and that, of course, is infeasible.

Well, if you know that it has happened then you can use the same trick to rewrite the prototype for Array.prototype.find() but you will have to implement the function yourself, the original definition (likely in C++ code) is not available.

I note one, extremely hacky, workaround that you might be able to adapt for Node.js insead of the browser:

Yes, fork the node-red-contrib-opcua node and fix it :wink: It has, after all, caused a lot of confusion and wasted time.

Certainly cost me a few hours.

Fortunately, they seem to have removed this in the latest version.

It was mostly academic at this point.

Cheers.

1 Like