JavaScript eval() 爲何使用eval()是一個壞主意 何時可使用eval()

 

----------------------------------------------------------------------------------------------------javascript

JavaScript eval() Functionjava

The eval() function evaluates or executes an argument.web

If the argument is an expression, eval() evaluates the expression. If the argument is one or more JavaScript statements, eval() executes the statements.express

若是參數是表達式,eval()函數會執行表達式;若是參數是js語句,eval()函數會執行js語句。跨域

----------------------------------------------------------------------------------------------------瀏覽器

MDN文檔安全

The eval() function evaluates JavaScript code represented as a string.服務器

eval()會「求值計算」一個計算機字符串app

Syntax

eval(string)

Parameters

string
A string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects.(表達式能夠含有變量或已存在對象的屬性)

Return value

The completion value of evaluating the given code. If the completion value is empty, undefined is returned(若是值爲空,就會返回undefined).less

Description

eval() is a function property of the global object(全局對象的屬性).

The argument of the eval() function is a string. If the string represents an expressioneval()evaluates the expression. If the argument represents one or more JavaScript statements, eval() evaluates the statements. Do not call eval() to evaluate an arithmetic expression; JavaScript evaluates arithmetic expressions automatically.

eval()函數是全局對象的屬性。

eval()函數的參數是字符串。若是是一個表明着表達式的字符串,eval()函數就會「計算求值」這個表達式;若是參數是js語句,eval()函數就會「求值計算」這些語句。不要調用eval()進行算術運算,js在算術運算時會自動調用。

If you construct an arithmetic expression as a string, you can use eval() to evaluate it at a later time. For example, suppose you have a variable x. You can postpone evaluation of an expression involving x by assigning the string value of the expression, say "3 * x + 2", to a variable, and then calling eval() at a later point in your script.

If the argument of eval() is not a string, eval() returns the argument unchanged(若是參數不是一個字符串類型,會將參數原封不動的返回).

In the following example, the String constructor is specified, and eval() returns a String object rather than evaluating the string.

You can work around this limitation in a generic fashion by using toString().

 

If you use the eval function indirectly, by invoking it via a reference other than evalas of ECMAScript 5 it works at global scope rather than local scope; this means, for instance, that function declarations create global functions, and that the code being evaluated doesn't have access to local variables within the scope where it's being called.

若是不是直接調用eval(),而是按照引用調用,則eval()的做用域是全局做用域而不是局部做用域。

Don't use eval needlessly!(若是不是須要,就不要使用eval() )

eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.

eval() is also generally slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.

 -----------------------------------------------------------------------------------------------------------------------------

Why is using the JavaScript eval function a bad idea?   eval() isn’t evil, just misunderstood

answer1:

  1. Improper use of eval opens up your code for injection attacks(注入攻擊)

  2. Debugging can be more challenging(調試困難) (no line numbers, etc.)

  3. eval'd code executes more slowly (no opportunity to compile/cache eval'd code)

Edit: As @Jeff Walden points out in comments, #3 is less true today than it was in 2008(第三點,在現代瀏覽器中,可能並不會很慢).

However, while some caching of compiled scripts may happen this will only be limited to scripts that are eval'd repeated with no modification. A more likely scenario is that you are eval'ing scripts that have undergone slight modification each time and as such could not be cached. Let's just say that SOME eval'd code executes more slowly.

answer2:

Two points come to mind:

  1. Security (but as long as you generate the string to be evaluated yourself(安全性問題,可是若是參數字符串是你本身產生的,即你能確保它是安全的,則使用eval()是沒有問題的), this might be a non-issue)

  2. Performance: until the code to be executed is unknown(性能問題), it cannot be optimized. (about javascript and performance,

answer3:

It's generally only an issue if you're passing eval user input(一般狀況下,只有對用戶輸入使用eval()會產生問題,由於這種狀況下你不能確保用戶會輸入什麼).

answer4:

Unless you are 100% sure that the code being evaluated is from a trusted source(若是你不是百分百肯定的eval()中的參數是值得信任的,安全的,那麼你的系統就頗有可能暴露在XSS跨域站點攻擊) (usually your own application) then it's a surefire way of exposing your system to a cross-site scripting attack.

Code Injection is a very serious issue for javascript if you are at all concerned about your user's data. Injected code will run (in the browser) as if it came from your site, letting it do any sort of shenanigan that the user could do manually. If you allow (third-party) code to enter you page, it can order things on behalf of your customer, or change their gravatar, or whatever they could do through your site. Be very careful. Letting hackers own your customers is just as bad as letting them own your server.

 

 --------------------------------------------------------------------------------

When is JavaScript's eval() not evil?

answer1:

I'd like to take a moment to address the premise of your question - that eval() is "evil". The word "evil", as used by programming language people, usually means "dangerous", or more precisely "able to cause lots of harm with a simple-looking command". So, when is it OK to use something dangerous? When you know what the danger is, and when you're taking the appropriate precautions.

因此,何時使用eval()函數是OK的呢?當你明白危險所在,當你作了一些適當的預防措施時。

To the point, let's look at the dangers in the use of eval(). There are probably many small hidden dangers just like everything else, but the two big risks(使用eval()有兩大點風險:1 性能表現  2 注入危險) - the reason why eval() is considered evil - are performance and code injection.

  • Performance - eval() runs the interpreter/compiler. If your code is compiled(若是你的代碼是編譯型的,那麼「使用」eval()會有性能問題), then this is a big hit, because you need to call a possibly-heavy compiler in the middle of run-time. However, JavaScript is still mostly an interpreted language(js仍舊是解釋性語言,因此調用eval()一般狀況下並非一個性能問題), which means that calling eval() is not a big performance hit in the general case (but see my specific remarks below).
  • Code injection - eval() potentially runs a string of code under elevated privileges. For example, a program running as administrator/root would never want to eval() user input, because that input could potentially be "rm -rf /etc/important-file" or worse. Again, JavaScript in a browser doesn't have that problem, because the program is running in the user's own account anyway. Server-side JavaScript could have that problem(代碼注入,服務器端的代碼注入會有大的風險).

On to your specific case. From what I understand, you're generating the strings yourself, so assuming you're careful not to allow a string like "rm -rf something-important" to be generated, there's no code injection risk (but please remember, it's very very hard to ensure this in the general case). Also, if you're running in the browser then code injection is a pretty minor risk(若是你在瀏覽器運行js,那麼代碼注入是一個至關小的風險), I believe.

As for performance, you'll have to weight that against ease of coding. It is my opinion that if you're parsing the formula, you might as well compute the result during the parse rather than run another parser (the one inside eval()). But it may be easier to code using eval(), and the performance hit will probably be unnoticeable. It looks like eval() in this case is no more evil than any other function that could possibly save you some time.

answer2:

eval() isn't evil. Or, if it is, it's evil in the same way that reflection, file/network IO, threading, and IPC are "evil" in other languages.

If, for your purposeeval() is faster than manual interpretation, or makes your code simpler, or more clear(若是使用eval()比你手動「解釋」快,讓你代碼更簡單,更清楚明白)... then you should use it. If neither, then you shouldn't. Simple as that.

answer3:

When you trust(當你信任數據來源十) the source.

In case of JSON, it is more or less hard to tamper with the source, because it comes from a web server you control. As long as the JSON itself contains no data a user has uploaded, there is no major drawback to use eval.

In all other cases I would go great lengths to ensure user supplied data conforms to my rules before feeding it to eval().

answer4:

Lets get real folks:

  1. Every major browser now has a built in console which your would-be hacker can use with abundance to invoke any function with any value - why would they bother to use an eval statement - even if they could?

  2. If it takes 0.2s to compile 2000 lines of javascript what is my performance degradation if I eval 4 lines of JSON(若是0.2s能夠compile2000行代碼,那麼我使用eval()處理4行代碼會帶來多少性能上的減小?)?

Even Crockford's explanation for 'eval is evil' is weak.

"eval is Evil The eval function is the most misused feature of JavaScript. Avoid it"

As Crockford himself might say "This kind of statement tends to generate irrational neurosis. Don't buy it"

Understanding eval and knowing when it might be useful is way more important. For example eval is a sensible tool for evaluating server responses that were generated by your software.

BTW: Prototype.js calls eval directly 5 times (including in evalJSON() and evalResponse()). JQuery uses it in parseJSON (via Function constructor)

相關文章
相關標籤/搜索