On Sun, 13 Mar 2011 16:53:59 +0100, Jarek Foksa <[email protected]> wrote:

Almost any modern JavaScript book recommends using subscript notation
(e.g. object[key]) instead of eval()

Stop right there. The two are fundamentally different. You can't use object[key] for most of the things you can use eval for (eval is a very powerful feature that
can do anything, whereas object property access does just that one thing).

because of the following three
reasons:
- evaled code execution is slow
- evaled code is less readable than the same code written with
subscript notation
- evaled code is insecure

- It's just not the right tool for the job. It's like putting in screws with
a sledgehammer. Thinking that it's even useful for the task shows complete
lack of knowledge of the better approach.

... ahem, ok, rant off.

While the first two arguments make perfect sense to me,  I don't
understand the last one.

AFAIK any code returned by client-side scripts should be treated as a
potential security risk. Thus it should be sanitized on the server
side before any further processing.

Eval takes client-side source code (a string) and executes it. The server
needs not be involved. In fact, if the server is involved, you don't need
eval at all, you can just embed the source directly in a script element.

The security problem is on the client itself, typically through Cross-Site
Scripting (XSS[1]) exploits.

So, security-wise, why would it matter whether eval() or any other
obscure code is used on the client side?

The only reason to use eval on the client is to execute client-side composed
source code from parts that weren't all available to the server.
That suggests that parts of the input is user provided, either directly or
through data fetched from another server (e.g. from an AJAX request).

The way you compose a string is typically by concatenation, so you are putting a user-input string into the code that you are executing. If you don't check that string throughly (more throughly than you will probably think to do), it means that the user can get any code executed on your page. That's a typical
XSS attack.

A primitive example:
  eval("document.write('Hello " + user.name + "');");
Hope you don't get Bobby Tables[2] as a user :)

Sure you can do safe vetting of untrusted input - but that usually boils
down to parsing it (if structured) or whitelisting, e.g., with a RegExp[3].

It is much much safer to just not use eval at all, and treat data as
data, not as (source) code.

Seeing this as a security problem highlights the problem, because it's easy
to see how a maliciously chosen name can break the above, but it's also likely
that some non-malicious user will enter a name that breaks the code (e.g.,
"O'Mally"). Creating source code at runtime is *fragile* (it can break in so many ways that you can't really control). Being fragile often also means that the fragility can be exploited by someone with malicious intent, but being fragile
should by itself be enough to avoid using the construction.


On top of that, the cases where you actually *need* eval, and can't do
the same thing simpler, faster and much safer, are so few and rare that it's
safe to say that if you use eval, you are doing something wrong.


/L
[1] Abbreviated like that probably because CSS was already taken (or because
    some people just love phonetic abbreviations).
[2] http://xkcd.com/327/
[3] Now you have two problems.
--
Lasse Reichstein - [email protected]

--
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to