Javascript and 'eval(....)', is it such a 'No-No' !!! - Page 1
Forum section: electronics / general

author: GlennSprigg
author_rank: Super Contributor
timestamp: May 11, 2019, 12:57:02 pm
content: I used to love coding in 'Javascript', especially with NON Internet/Web-related applications.I loved using 'eval()' when I wanted variable inputs/strings to be be 'variably' interpreted in 'real-time'.However, I often got shot down in flames, due to security loopholes...Are they that bad? or just considered sloppy!

author: Yansi
author_rank: Super Contributor
timestamp: May 11, 2019, 02:17:25 pm
content: It the same as if you would make your local computer command line publicly available...

author: Ian.M
author_rank: Super Contributor
timestamp: May 11, 2019, 02:31:37 pm
content: It depends. eval() can do absolutely anything that's permitted in the language with the privileges of the script that invokes it. If you use eval() on a string from a source you don't 100% trust, you are a moron and its a massive security hole. OTOH if your code custom builds the eval expression string, carefully sanitising any parts of it that are user or remote input to ensure they don't contain unwanted sub-expressions, its no big deal. Also in a web based client server scenario, trusting any Javascript run on the client is unwise as there are more ways of tampering with the data, the script sourcecode or client Javascript methods than you can shake a stick at!

author: magic
author_rank: Super Contributor
timestamp: May 11, 2019, 03:56:15 pm
content: What are some typical instances you end up using it in? Chances are there may be different solutions and in that sense it might be considered "sloppy".But it only gets seriously bad when, as is well know, somebody could possibly insert undesirable code into the string and cause problems.

author: GlennSprigg
author_rank: Super Contributor
timestamp: May 14, 2019, 11:02:12 am
content: Quote from: Ian.M on May 11, 2019, 02:31:37 pm(Thanks to others too!).Iwouldshow a typical example, but all that coding is on a Laptop that is in BITS now due to repairs,and I can't lay my hands on my SATA/USB cable to view/retrieve the files, right now !Grrr...Yea... I did 'not' code it to wait for an 'input' string, haha! And there are 'no' servers/web involved.I 'had' started some major revisions, which is why I asked the question, before continuing it shortly.I had created someextension modulesfor a particular real-timePhysics-Simulationpackage/software.What they 'did', (and quite successfully!), was calculate much more realisticMagnetic Fields, &Gravity,between objects, and the resultanttrue motion & orbitsetc. in graphical animations. Many parameterscan be specified, based on very small to very large 'objects', of any 'mass' or 'volume', ranging from'touching' objects through to 'stellar' situations!....People could intervene via certain parameters, to specify certainvalues/names. My 'coding' would 1stcheck 'anything' entered, to ensure there wasNOhidden 'coding', and that applicable 'text' & 'numbers'were acceptable and within 'range' for the simulation ! before being passed/parsed(!) to 'eval()'.The 'reason' for using 'eval' is that my software would actuallyCREATEnewObject-Properties, on the'fly' that the underlying 'engine' would understand, and that people could 'use' on the fly, either fromthe 'Console', orwithin their own codingthat utilized my modules! (Clear as mud)It all worked well !! My new revisions were to 'attempt' more realism, by considering 'irregular' shapedbodies!, (it's hard!), and the controversial aspect, (not understood/believed by many), that an 'object'like a small sphere, 'inside' of an empty shell of mass, has NO unbalanced force of Gravity to the shellNot to mention some mass/inertia/acceleration mods... Oh!... And when objects are actually 'touching'then the forces are 'not' in any way infinite, if say 'magnets' touch, (inverse-squared law), or gravitationallyat a 'maximum', as the masses have 'volume', and rough surfaces.... (Not going in to that here !!)

author: NivagSwerdna
author_rank: Super Contributor
timestamp: May 14, 2019, 12:15:21 pm
content: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

author: apis
author_rank: Super Contributor
timestamp: May 14, 2019, 01:12:00 pm
content: Quote from: GlennSprigg on May 11, 2019, 12:57:02 pmOne problem might be that others see what you did and repeat it where it would be a problem. A lot of people just mindlessly copy paste and use trial and error until something appears to do what it's supposed to (which is often fine and how we learn to do things).A bigger risk though is that someone else might later take your code and use it for something else. They might be completely unaware that you implemented some functions with eval() and use it somewhere unsafe. That someone else might even be you in the future when you have forgotten about how you implemented it.Don't know about your particular case, but for more serious programming it should probably be considered a no-no in general.

author: magic
author_rank: Super Contributor
timestamp: May 14, 2019, 05:17:50 pm
content: You don't need eval to create objects or methods. This is perfectly valid JS code:Code:js> var initial=1js> var increment=3js> var counter={count:initial,advance:function(){this.count += incrementreturn this.count}}js> counter.advance()4js> counter.advance()7js> counter.advance()10As you see, I have actually run it in an interactive interpreter to verify that it's good.At the time of counter creation, initial and increment are normal variables whose value gets embedded in the counter object. They could be user-supplied numbers, no problem.The whole code can be packaged as a function with two parameters and called 100 times to create 100 different counters, it will work as expected.editOkay, I actually lied a bit. It's not the value of increment which is embedded in the counter but a reference to that variable. Changing increment changes behavior of counter:Code:js> increment=55js> counter.advance()15js> counter.advance()20But if you create a function make_counter, each execution of make_counter gets its own copy of increment. Therefore each created counter will use its own copy of increment and the counters will be independent of each other. Try it, it works.

author: Red Squirrel
author_rank: Super Contributor
timestamp: May 14, 2019, 09:31:06 pm
content: I think the key is to just not trust user input. Consider what happens if you have user provided data put into an eval. If they put code they could inject stuff.The user can now enter code and have it execute. For client side code it probably won't do much but for server side it could be devastating.Now what I personally do is as soon as I get user input I sanitize it right away. In the case of a search string, it's probably as simple as removing all non alpha numeric characters. Maybe allow a couple special characters that you'd want to be searchable.For things like names or any data that's simply going into a database, I personally like to just "htmlize" all the special characters. Quotes are especially important to sanitize. For numbers then simply making sure it's a number and removing all other characters does the trick.User input can come from many sources such as forms, uploaded files (if you need to process the file in any way, or the file name), and even cookies. Depending how paranoid you are you can even treat data from the database the same way, in case someone tampered with the database. Though in that case you are already compromised so it's too late really.

author: sleemanj
author_rank: Super Contributor
timestamp: May 14, 2019, 09:50:44 pm
content: It's a bit like using goto.There is nothing inherently wrong about using eval or goto. Just think about how you are using it. In terms of eval, where the data comes from, or importantly, ways in which the data could come from somewhere undesirable.Don't go using it for just parsing a JSON string, all modern browsers support theJSON.parsemethod which will not risk executing code.The most prominent example of a bad idea for javascript eval usage of course is that you would absolutely not want to blindly eval any data that was passed in to the server by the user and then spat back out to their browser because you can not be sure that data did actually come from the user and not a malicious actor, in other words, this is a super bad idea...Code:<script type="text/javascript">eval('<?phpecho$_REQUEST['EvilEval'];?>');</script>

author: golden_labels
author_rank: Super Contributor
timestamp: May 14, 2019, 10:00:48 pm
content: Usingevalis like taking a shortcut through a mine field under heavy artillery fire. Theoretically you have chances of surviving, but is this a good way of reaching the destination? Alternatively see it as using a dragon to light a candle standing on top of your head. Would you?¹There may be legitimate cases of usingeval-like constructs in a program (not neccesserily in ECMAScript code). But since they’re that risky to use, you have to put a lot of effort to ensure proper operation. Way more work than you could allocate while writing an ad-hoc solution. It may seem easy, because just a few simple steps are enough to patch the most obvious shortcomings. Reality proves over and over, and over, and over, and over (×1000) again, that his is not true and you will experience a failure. Therefore if you aim at writing good code, you simply do not use it.The valid uses ofeval-like solutions are always in libraries, which are dedicated to using exactly that thing. Usually made by a team of people from different background, usually reviewed and checked by many others, experts included. And they still happen to fail!____¹ Honestly, I probably would… just to see a dragon.

author: GlennSprigg
author_rank: Super Contributor
timestamp: May 20, 2019, 11:23:25 am
content: Thank you to all, for your comments/thoughts. Have taken it all onboard!!Just remember that I didn't/wouldn't leave open input-strings for eval(). As I stated...My 'coding' would 1st check 'anything' entered, to ensure there was NO hidden 'coding', and that applicable'text' & 'numbers' were acceptable and within 'range' for the simulation ! before being passed to 'eval()'.However, when I can get my 'coding' back from my main Laptop/HDD, then I may re-post this, so you can bettersee what I was trying to do. (Or did!). And maybe then we could look at 'better' work-arounds !! Thanks.

author: technix
author_rank: Super Contributor
timestamp: May 22, 2019, 08:06:54 pm
content: All those eval()'s are just evil. It might be a good idea however you should almost always heavily guard it, and try your damned best not to use it.

author: golden_labels
author_rank: Super Contributor
timestamp: May 22, 2019, 10:33:07 pm
content: Usingevalis like connecting the neutral wire to a metal case in a device with a 2-contact plug, while claiming you are always remembering about polarity while plugging it in. It’s like driving a motorbike wrong way, claiming you always see what’s in front of you — until one day you miss some minor side road with no visibility, with a large truck going out of it.

author: magic
author_rank: Super Contributor
timestamp: May 22, 2019, 10:50:05 pm
content: QuoteOkay, we get it, you are an evalphobic person. But there really isn't much that can go wrong if you only expect a number and verify that the string contains nothing but digits.In most cases there are more straightforward solutions than eval, though.