Run function whenever var is defined - javascript

I am working on a project with a lot of user-generated code(inspired by this video http://vimeo.com/36579366). What I want to do is to eval() a chunk of user-input code, and run a function every time a var is defined, or 2 variables are multiplied, or some other action occurs.
Is there a way to do this in JS?
Obviously, I could search the field for "var ..." and then read what comes next, and then do whatever I need to do with that information, but, for a number of reasons, I would rather do it "legitimately" where I actually react to something being executed.

You can use the Intercession API in certain versions of Javascript (also known as proxies). From this you can redefine what happens when objects mutate by writing your own code.
If that's not possible, but you know the names of the variables in advance, you can use setters, getters, or a polyfill for Object.watch to achieve the same effect.
If you don't know what the variable names are going to be, I recommend running the user-defined Javascript through a parser like Esprima to obtain an AST. From this you can inject arbitrary syntax directly into the AST when you see variables being defined (or hoisted), and then compile back to working code. You'll be looking for JSON objects with "type": "VariableDeclaration".

Related

How do I know JavaScript return types automatically for non-primitives/user-defined types and promises?

I'm working with an SDK and I want to go through all the namespaces shown in its API documentation and verify that all the functions return the correct type of object or if the function returns a promise. However, there are way too many functions to try this manually.
I came across ES6 Iterate over class methods and that might work for functions that don't require input variables but many of the functions in the API I want to try out require inputs as well. It seemed like maybe passing in the .js file process it externally using something like Python might be a good idea but I haven't been able to identify a solution yet.
Overall, I would like to be able to compare all the expected return types from the API documentation vs actual return types for the respective functions and put up the differences on an excel sheet for later use.
The first approach you should try is to see if there is a documentation for the SDK/API where you can read and see what the expected return values are. Due to the fact that it is a JavaSvript api, you kind of need that, or need to read through the code yourself, to know what ALL possible return values are.
If the code itself is documented with JSDocs tags, you could check what they are defined to return, something that most IDE's have support to show you during your coding.
JavaScript is a dynamically typed language, I.E., a function could basically return anything. So the best way to know what you should expect is to check for documentation!

Restrict/validate JavaScript code to a specific library

I have a project where users can submit JavaScript code. However, I want to check, that inside the submitted code only methods and properties of a certain javascript object are used. e.g. my object's name is X, then users should only be allowed to use:
X.method1();
X.method2();
X.method3(X.propertyA);
if(X.booleanPropertyB)
{
X.method(X.propertyWOW);
}
They should NOT be allowed to create new vars or use properties or methods of javascript objects like document, window or navigator.
What would be a good approach to validate the scripts according to these rules? Either inside JavaScript or by a server side validator e.g. written in Java.
So far my idea is to use a server side validator and check that the first non-whitespace characters after every semicolon as well as after every opening curly bracket are "X." or a reserved word like if, else, while, for etc
However, I think I'm over-simplifying it and would like to know your thoughts on whether this is a reasonable approach.
Thanks.
Your problem has two parts:
Make sure users use your object X
You can achieve this by mocking your object in tests and checking if relevant object methods are used. See here how it is done with Jasmine
Restrict users from accessing certain APIs
The easy way to achieve it is to run the user code inside a closure. e.g.
;(function(window, document, console, eval, alert, setTimeout, setInterval){
// run user code here
// window, document etc. are inaccesible and null in this context
})(null, null, null, null, null, null);
This, however, does not prevent users to declare their own stuff, vars, functions and alike.

How can I check if a function is a pure function?

I'm working on react-metaform, and one of my challenges is that I need to allow the end-user to define metadata as functions. Example:
socialSecurityNumber.required: (m) => m.type == 'person'
The problem is obvious: I cannot trust the user. So, these are the precautions i'm planning to make:
User-defined functions should be pure function. In the sense that, these functions can only access their parameter, nothing else.
User-defined functions will run in an environment that is resilient to exceptions, too long execution times and infinite loops. (I'm not worried about this right now).
The question is: How do I make sure a user-defined function only accesses it's parameters and nothing else?
I would use esprima to parse users' JavaScript functions that are stored in files or in a database. And I would allow to run only code that passes the parsing test (only whitelisted features - using local variables, parameters, ...).
You can start with a very simple checking code that only allows very limited scripts and progressively improve it. However, I guess you will put a lot of effort to the solution over time because your users will always want more.
Note: Angular.js uses for its dependency injection this kind of 'trick': https://jsfiddle.net/987Lwezy/
function test() {
console.log("This is my secret!");
}
function parser(f) {
document.body.innerHTML = test.toString();
}
parser(test);
You could use https://github.com/lcrespom/purecheck. It hasn't been updated in a while, but seems to support what you need.

Is there any real danger to overriding the default 'console' in node?

I'm a habit driven creature, and console.log/console.error/etc happens to be the thing I just instinctively use to print things out. However, I'm trying to drive all my logging in node to 'winston'. I'd prefer to do something like var console = require('./modules/logger'); at the top of my file and then just use console.whatever as usual.. tapping into extra arguments as necessary (otherwise the api is pretty much the same). Since this is localized to the file I'm working with and not some sort of global change, is there any danger in setting 'console' to that module's export? And not just "well, it might be confusing for someone else".
I did notice this question pop up as a similar question, but it doesn't really answer whether there's a danger behind it. And there's some other questions that ask if you can override some of node's core, but I'm not doing that - I'm just making a local reference using the same name as a "magic" global.
Other than possibly overriding existing console functions in a non-standard (i.e. unexpected) way, I do not see any danger in replacing the global console with your own object as long as it provides all the expected functions and calling conventions (function signatures) as the default console. I've done it many times without issue.
If you do provide some non-standard implementation of an existing function on the global console with a different signature than other code expects, you're bound to run into problems.
If you do your replacement in a module or function scope, only references in that scope would be affected.

localStorage - use getItem/setItem functions or access object directly?

Are there some benefits of using the methods defined on the localStorage object versus accessing the object properties directly? For example, instead of:
var x = localStorage.getItem(key);
localStorage.setItem(key, data);
I have been doing this:
var x = localStorage[key];
localStorage[key] = data;
Is there anything wrong with this?
Not really, they are, basically, exactly the same. One uses encapsulation (getter/setter) to better protect the data and for simple usage. You're supposed to use this style (for security).
The other allows for better usage when names(keys) are unknown and for arrays and loops. Use .key() and .length to iterate through your storage items without knowing their actual key names.
I found this to be a great resource : http://diveintohtml5.info/storage.html
This question might provide more insight as well to some: HTML5 localStorage key order
Addendum:
Clearly there has been some confusion about encapsulation. Check out this quick Wikipedia. But seriously, I would hope users of this site know how to google.
Moving on, encapsulation is the idea that you are making little in and out portals for communication with another system. Say you are making an API package for others to use. Say you have an array of information in that API system that gets updated by user input. You could make users of your API directly put that information in the array... using the array[key] method. OR you could use encapsulation. Take the code that adds it to the array and wrap it in a function (say, a setArray() or setWhateverMakesSense() function) that the user of your API calls to add this type of information. Then, in this set function you can check the data for issues, you can add it to the array in the correct way, in case you need it pushed or shifted onto the array in a certain way...etc. you control how the input from the user gets into the actual program. So, by itself it does not add security, but allows for security to be written by you, the author of the API. This also allows for better versioning/updating as users of your API will not have to rewrite code if you decide to make internal changes. But this is inherent to good OOP anyhow. Basically, in Javascript, any function you write is a part of your API. People are often the author of an API and it's sole user. In this case, the question of whether or not to use the encapsulation functions is moot. Just do what you like best. Because only you will be using it.
(Therefore, in response to Natix's comment below...)
In the case here of JavaScript and the localStorage object, they have already written this API, they are the author, and we are its users. If the JavaScript authors decide to change how localStorage works, then it will be much less likely for you to have to rewrite your code if you used the encapsulation methods. But we all know its highly unlikely that this level of change will ever happen, at least not any time soon. And since the authors didn't have any inherent different safety checks to make here, then, currently, both these ways of using localStorage are essentially the same. Except when you try to get data that doesn't exist. The encapsulated getItem function will return null (instead of undefined). That is one reason that encapsulation is suggested to be used; for more predictable/uniform/safer/easier code. And using null also matches other languages. They don't like us using undefined, in general. Not that it actually matters anyhow, assuming your code is good it's all essentially the same. People tend to ignore many of the "suggestions" in JavaScript, lol! Anyhow, encapsulation (in JavaScript) is basically just a shim. However, if we want to do our own custom security/safety checks then we can easily either: write a second encapsulation around the localStorage encapsulate, or just overwrite/replace the existing encapsulation (shim) itself around localStorage. Because JavaScript is just that awesome.
PT
I think they are exactly the same, the only thing the documenation states is:
Note: Although the values can be set and read using the standard
JavaScript property access method, using the getItem and setItem
methods is recommended.
If using the full shim, however, it states that:
The use of methods localStorage.yourKey = yourValue; and delete
localStorage.yourKey; to set or delete a key is not a secure way with
this code.
and the limited shim:
The use of method localStorage.yourKey in order to get, set or delete
a key is not permitted with this code.
One of the biggest benefits I see is that I don't have to check if a value is undefined or not before I JSON.parse() it, since getItem() returns NULL as opposed to undefined.
As long as you don't use the "dot notation" like window.localStorage.key you are probably OK, as it is not available in Windows Phone 7. I haven't tested with brackets (your second example). Personally I always use the set and get functions (your first example).
Well, there is actually a difference, when there is no local storage available for an item:
localStorage.item returns undefined
localStorage.getItem('item') returns null
One popular use case may be when using JSON.parse() of the return value: the parsing fails for undefined, while it works for null

Categories

Resources