JavaScript to evaluate a simple math string such as 5 * 1.2 (eval / white-list?)

I have an onchange input that converts numbers like 5,008.00 to 5,008.00 .

I am considering expanding this to allow simple calculations. For example, 45*5 will be automatically converted to 225.00 .

I could use the whitelist ()+/*-0123456789. and then pass the result to eval , I think these characters are safe to prevent any dangerous injections. This assumes that I am using the appropriate try / catch , because a syntax error could be generated.

  • Is this an OK white list and then pass it to eval ?

  • Recommended Revised Whitelist

  • Do you recommend a different approach (maybe there is already a function that does this)

    I would rather keep it lightweight. This is why I like the eval / white-list approach. Very small code.

What do you recommend?

+4
javascript math onchange
Mar 28 '12 at 19:23
source share
3 answers

This whitelist seems safe for me, but it is not such an easy question. In some browsers, for example, the same line:

 /.(.)/(34) 

equivalent to this:

 new RegExp('.(.)').exec('34') 

and therefore returns an array ['34','4'] . It's safe"?

Thus, although the approach can probably be made secure, it can be a very complex proposition. If you go ahead with this idea, I think you should use a much more aggressive approach to validate your inputs. Your principle should be "this is a member of a well-defined rowset that is known to be" safe ", and not" this is a member of a poorly defined rowset that excludes all rows that are known to be "unsafe" "". In addition, in order to avoid the risk that the operators looked in that you did not consider (for example, ++ or += or something else), I think you should insert a space before each character other than a digit, and to avoid the risk the occurrence of parentheses that cause the function to be called, I think you should deal with them yourself by repeatedly replacing (...) space plus an evaluation result ... (after confirming that this result is a number) plus a space.

(By the way, how did it happen = in your whitelist? I just can’t understand that this is useful!)

+3
Mar 31 '12 at 16:15
source share

Given this extremely strict whitelist, I see no way to commit a malicious action, except that you have selected an exception. The brace trick will not work, since it requires square brackets [] .

Perhaps the safest option is to change the parser of the default values ​​for pages only to accept numbers and throw away something else. Thus, potentially malicious code in the link will never go to eval .

This only leaves the user able to enter something malicious into the field, but why even bother with it? The user already has access to the console (Dev Tools), which they can use to execute arbitrary code.

+2
Mar 31 '12 at 18:40
source share

The often forgotten problem with eval is that it causes problems for javascript minifiers.

Some minifiers, such as YUI, take a safe route and stop renaming variables as soon as they see the eval statement. This means that your javascript will work, but your compressed file will be larger than necessary.

Others, such as the Google Closure Compiler, will continue to rename variables, but if you are not careful, they may break your code. You should avoid passing strings with variable names in it for eval. for example.

 var input = "1+2*3"; var result = eval("input"); // unsafe var result = eval(input); // safe 
0
Mar 31 2018-12-12T00:
source share



All Articles