setInterval() is different between browser and Node - javascript

The global methods setInterval and setTimeout are different between browser (window) and NodeJS (global). The behavior is quite the same. Both doing the same.
See docs about NodeJS and Browser. In Node the returned value is a instance of a Timeout class. The browsers methods returns just a number, a handler id.
How to work with this difference if you developing for browsers but testing with Node, because test-framework engine is node (e.g. Jest). Do I need to switch to a browser test-engine?
(btw) Also, in my case I restrict all global variables. So I have to access only by the scope name. e.g. window.setInterval or global.setInterval not just setInterval. (It's a tslint rule no-restricted-globals)
Anyway there is a type conflict between Node's and browser's timer functions.
Is there a good practice to handle it? Do I have to switch my test-engine? But finally they doing the same. Maybe I have to cast to any-type?
I know this is not a JavaScript specification. It's the enviroment dependency. I do not say that they should be exactly the same. I'm just wondering how to deal with it when I run unit tests on node-js but I'm developing for browser. Currently only the return values are different. The behavior itself seems to be equal.

Related

How can I sandbox code in an application with dynamically loaded, untrusted modules?

I'm making a game in Electron and I want it to support mods. Sometimes those mods will need to use custom logic, which leaves me with the issue of dynamically loading their code and I'm finding it hard to come up with a way to do that securely.
What I've considered
Ideally, I'd like to execute the mod scripts while passing just the few safe game objects they need as parameters, but that seems to be impossible (no matter the solution, that code can still access the global scope).
Most importantly, I have to prevent the untrusted code from accessing the preload global scope (with Node APIs), so require or anything else done in the preload is out the window.
Therefore that code has to be executed in the renderer.
My solution so far
I can either read the files in preload using fs or directly in the renderer using fetch. I have nodeIntegration set to false and contextIsolation set to true, and trusted code loaded by the preload script is selectively passed to the renderer through a contextBridge. The code which accesses Node APIs is properly encapsulated.
Unfortunately, that still leaves me with having to execute the unsafe code somehow, and I don't think there's any other way than to use eval or Function. Even though malicious code could not access Node APIs, it would still have full access to the renderer global scope, leaving the application vulnerable to, for example, a prototype pollution attack.
To sum up:
The safer place to execute untrusted code is clearly in the renderer
There is no alternative to using eval or Function
This leaves the renderer global scope vulnerable to attacks which I can try to mitigate but can never make it completely safe
My first question: are these assumptions true, or is there a better way to do it?
The risks and how to mitigate them
So the potentially malicious code has access to the renderer global scope. What's the risk?
Well, any sensitive user data will be safely stored in the preload, the same goes for access to the user's computer with Node APIs. The attacker can break the game (as in, the current 'session'), but I can catch any errors caused by that and reload the game with the malicious mod turned off. The global scope will only hold the necessary constructors and no actual instances of the game's classes. It seems somewhat safe, the worst thing that could happen is a reload of the game.
My second question: am I missing anything here regarding the risks?
My third question: are there any risks of using eval or Function that I'm not thinking of? I've sort of been bombarded with "eval bad" ever since I've started getting into JS and now I feel really dirty for even considering using it. To be exact, I'd probably be using new Function instead.
Thank you for reading this long thing!
There is no general solution for this, as this heavily depends on the structure of the project itself.
What you could try is to use espree to parse the unsafe code, and only execute it if there is no access to any global variable.
But that most likely will not prevent all attacks, because you might not think certain other attacks that might be possible due to the way the program is structured, require (or any other way to include/load other scripts) in that unsafe code could also open side channels allowing certain attacks.
eval and new Function are not bad in general, at least not as bad as loading/including unsafe code in any different way. Many libraries use code evaluation for generated code, and that's the purpose of those functions. But it is often misused in a situation in which there no need for that and that is something that should not be done.
The safest way is most likely to run the code in a WebWorker and define an API for the Mods to communicate between the mod and the application. But that requires to serialize and deserialize the data, when passing it form the app to the mod and the other way round, this can be expensive (but this is what is done e.g. with WebAssmebly). So I would read a bit how communication is solved with WebAssembly.

Do the most current JavaScript/ECMAScripte compilers optimize out unnecessary variable assignment when returning the value from a function call?

Say we are inside an object that implements file handling. I want to write the code for easier readability.
Example of code where it can be difficult to tell the return type, especially when there are multiple nested function calls:
function create() {
return doCreateAction();
}
This example is more readable by introducing a clarifying variable:
function create() {
var fileHandle = doCreateAction();
return fileHandle;
}
In theory, the second version could perform identically because the compiler has to store the result from doCreateAction() temporarily anyway (probably inside some hiddenm, anonymous, short-lived temp variable). It this code any slower when assigning to a named variable?
I would say either they do optimize the variable out, or it's not worth bothering; and that in either case you have bigger fish to fry. :-) But there is an interesting aspect to this in relation to tail calls.
But first, in terms of simple performance: Empirically, this simplistic, synthetic test suggests that the performance of the function doesn't vary depending on whether there's a variable. Also note that a minifier will likely remove that variable for you before the JavaScript engine gets a look in, if you use a decent minifier.
Moving on to tail-calls: As you may know, as of ES2015 in strict mode the specificaton requires tail-call optimization (TCO), which means that when function A returns the result of calling function B, rather than having B return its result to A which then returns it to the caller, A passes control directly to B which then returns the result to the caller. This is more efficient in several ways (avoids creating another frame on the stack, avoids a jump).
Now, it may not matter because development of TCO in JavaScript engines is at least stalled if not dead. The V8 team developed an early version but abandoned it, SpiderMonkey doesn't have it either; as far as I know, only JavaScriptCore in Safari does TCO. But if I read the spec correctly (no mean feat), your first example has doCreateAction in the tail position and so can be optimized via TCO, but your second does not.
So there could be implications in that regard, if and when TCO is ever implemented widely and if, when it is, implementations go slightly beyond the spec for cases like this where clearly it is, in effect, a tail call.
I used to be fairly strict about using a variable in that situation for debugging purposes; moderately-recent versions of Chrome's devtools make it unnecessary for that purpose however (and of course, a minifier will remove it anyway): If you step into a return, you see the return value in the local scope list of variables. Of course, that's only useful if you're using Chrome's devtools (Firefox's, for instance, don't do this [yet?]).

nodejs need use 'strict use'?or what is the best practice of node's strict mode?

I'm a new to node.js and javascript.I checked code examples of node.js and it used use strict mode.
For example, a server.js:
'use strict';
//some server code
Also, I got to know that use strict is present at head of every js file.
It confused me and so I want to know what is best practice in Nodejs to use strict mode?
Thank you all, My question is focus on the strict mode. In this mode, some code mistake can be reported. In back-end, the strict error reporter also run? And If I need use it, I should add it in every js file header? Or add it in main file(server.js or etc.) head? Or use some node.js self style?
Use it always. If nothing else, it ensures that your code is properly written, and cross browser compatible as it can be. It also will reveal mundane syntax errors that would otherwise go unfound, and lead to hours of unnecessary debugging.
“use strict” is a behavior flag you can add to to first line of any JavaScript file or function. It causes errors when certain bad practices are use in your code, and disallows the use of certain functions, such as with.
References:
Restrictions on Code in Strict Mode by Microsoft MSDN
Node.js Best Practices
Nodejs is server-side javascript, so many coding practices are similar in both. So using strict mode is common.
It ensures that you are not violating certain coding conventions like undeclared variables x=14;, use of specific variable names arguments,eval which are names of few global variables and functions.

How do I tell Mocha to only run a certain test in the browser (and not in node.js)?

I’m using Mocha to test modules in my javascript application. One of my modules depends on there being a document object, so the test for that module fails when I run my tests in node.js and passes in the testing page in the browser.
How can I tell Mocha to only run this specific test in the browser and not in node.js?
if(window && window.document){ runBrowserOnlyTests(); } //?
Oops. Forgot to check for existence of window first. Sorry I didn't catch that. You could just check for 'document' globally but explicit seems best in this case as document or window could easily be some other var in Node. If somebody defined an object named window in Node with a document property, well, that's just ignorant. Although I suppose you could then check constructor names if you were worried about that but this strikes me as sufficient, especially since I assume node modules each have their own global objects or their wouldn't be much point to the require method. (somebody correct me if I'm wrong)

intercepting javascript alert()..? is it acceptable?

I just found we can intercept the javascript alert() native call and hook the user code before the actual execution. check out the sample code..
function Test(){
var alertHook=function(aa){
this.alert(aa);
}
this.alert("aa");
this.alert = alertHook;
alert("aa");
}
so everytime i call alert("aa") is been intercepted by my alertHook local function. But the below implementation with the small change does not work.
function Test(){
var alertHook=function(aa){
alert(aa);
}
alert("aa");
alert = alertHook; //throws Microsoft JScript runtime error: Object doesn't support this action
alert("aa");
}
it throws Microsoft JScript runtime error: Object doesn't support this action.
I dont know how this.alert = alertHook; let me intercept the call, but alert=alertHook; not.??
So i assume using this to intercept any native js methods.? is that right?
And is that acceptable? because this way i can completely replacing any native JS calls with my own methods??
UPDATE:
I asked is that acceptable? because how this is a good approach having eval() and letting users to replace native function calls?
And its responsibility of a language to protect developers from the misleading features, replacing the native js calls in a window level(or in a common framework js file) would crash the whole system.. isn't it??
i may be wrong in my opinion because i dont understand the reason behind this feature..? I never seen a language that let developer to replace its own implementation..
Depending on how Test(); is being called, this should be the window Object.
I believe Microsoft allows overwriting native JS functions only by specifying the window object.
So window.alert = alertHook; should work anywhere.
is it acceptable?
Yes it is. This is a major strength for the flexibility of the language, although I'm sure there's better alternatives instead of overwriting native behavior.
Overwriting native JavaScript functions isn't really a security issue. It could be one if you're running someone elses code that does it; but if you're running someone elses code there's a lot of other security issues you should be concerned about.
In my opinion, it never is good practice to redefine the native functions. It's rather better to use wrappers (for instance, create a debug function that directs its output to alert or console.log or ignores the calls or whatever suits your needs).
As for why JScript throws an exception with your second example and not the first one, it's easy. In the first example, you create a property called alert in your local scope, so when you refer alert you'll be referring this.alert rather than window.alert. In the second example, the alert you're referencing is the one from window, so assigning a different function to it will fail.
And its responsibility of a language to protect developers from the misleading features, replacing the native js calls in a window level(or in a common framework js file) would crash the whole system.. isn't it??
Not true, replacing the native call only hooks into it, replaces it: it does not rewrite the native at all. Crashing the "whole" system; JavaScript runs in a Virtual Machine, it's interpreted, so the chance of crashing the "whole" system (i.e. Blue Screen of Death?) is very very small. If so: it's not the programmers fault, but the implementation of JavaScript which is causing the error.
You can consider it as a feature: for instance, if you load a JavaScript from someone else's hand, you can reimplement some functions to extend.
Protection to the programmer is like keeping a dog on the leash: only unleash it, when you trust the dog! Since JavaScript runs in a Virtual Machine, any programmer can be unleashed -- if the implementation is secure enough, which it is (most of the time?)

Categories

Resources