Using XMLHttpRequest without 'eval'

M

My Pet Programmer

The way I usually set up and work with the XMLHttpRequest to execute
server side functions and get results is this:

var url = "someurl?params=" + params;
var conn = createRequest(); // gets an XMLHttpRequest object

conn.open("GET", url);
conn.onreadystatechange =
function () {
if (conn.readyState == 4 && conn.status == 200) {
var ret = conn.responseText;
var data = eval ( "(" + ret + ")" );

}
};

(The above is a highly snipped version without any of the usual checks
and balances, it's for illustration only)

What I'm curious about is how to get the data back and get it read with
using eval(). All of the examples I have seen show the use of eval as if
it were just perfectly ok and normal, and most of everthing I've read
about eval says never, ever use it.

Do one of you guys have any links/advice/vitriol I could use to get my
head around a better way?

All the best,
~A!

--
Anthony Levensalor
(e-mail address removed)

Only two things are infinite, the universe and human stupidity,
and I'm not sure about the former. - Albert Einstein
 
D

David Mark

The way I usually set up and work with the XMLHttpRequest to execute
server side functions and get results is this:

var url = "someurl?params=" + params;
var conn = createRequest(); // gets an XMLHttpRequest object

conn.open("GET", url);
conn.onreadystatechange =
   function () {
     if (conn.readyState == 4 && conn.status == 200) {
       var ret = conn.responseText;
       var data = eval ( "(" + ret + ")" );

     }
   };

(The above is a highly snipped version without any of the usual checks
and balances, it's for illustration only)

It is missing the send too.
What I'm curious about is how to get the data back and get it read with
using eval(). All of the examples I have seen show the use of eval as if
it were just perfectly ok and normal, and most of everthing I've read
about eval says never, ever use it.

Don't believe most of what you read. Never use eval unless its use is
appropriate. Evaluating JSON data is an appropriate use. Just don't
do it if the data comes from somebody else's server.

Alternatively, you could use a JSON parser, but it doesn't make much
sense to do so if the data comes from your own server.
 
M

My Pet Programmer

David Mark said:
On Dec 27, 8:58 pm, My Pet Programmer <[email protected]> [snip]
(The above is a highly snipped version without any of the usual checks
and balances, it's for illustration only)

It is missing the send too.


Shoot. I gave that to someone as an answer to their problem not three
days ago, too. Yeesh.

[snip]
Don't believe most of what you read. Never use eval unless its use is
appropriate. Evaluating JSON data is an appropriate use. Just don't
do it if the data comes from somebody else's server.
That makes a lot of sense, and I only use this method when the data is
from my own servers anyway, I'm just hearing a lot of eval is bad about.
Thanks for the clarification
Alternatively, you could use a JSON parser, but it doesn't make much
sense to do so if the data comes from your own server.

Yeah, I thought about doing that, it just seemed like to much more work
for so little actual gain when the data comes from a file one directory
over.

Thanks, David.

~A!

--
Anthony Levensalor
(e-mail address removed)

Only two things are infinite, the universe and human stupidity,
and I'm not sure about the former. - Albert Einstein
 
M

My Pet Programmer

Randy Webb said:
My Pet Programmer said the following on 12/27/2007 8:58 PM: [snip]

Depends on what type of data it is. If it is HTML code, with script
snippets in it, then eval has a fatal flaw in it with regards to it.
Even if it is JSON, it could still have a fatal flaw in it if you leave
that function, go to a different function, then try to do something with
the data that you eval'ed unless you do something with it to change the
way it handles it.

It is JSON data exclusively, I don't use the object for loading HTML
code, I build it on the fly every time, mostly because I enjoy the
control over it in my script. If something changes on the page from what
I expected when I wrote the php, my script doesn't much care, and not
too much gets screwed. And it's never XML because I just hate the parsing.
[snip]
Anything that says "never, ever use eval" is just as bad as using eval
when you don't need to. The rule of thumb is "Don't use eval for
anything other than its intended purpose". The purpose of eval is to
evaluate code "not known at runtime".

That makes sense too, just like David said. I tend to think absolutes
are limiting and overblown most of the time anyway.
Depends on what type of data is being returned. If it is not JSON,
search the archives for loadHTMLFragment.

<URL:
http://groups.google.com/group/comp...f?lnk=gst&q=loadhtmlfragment#96dd313cb56fb75f>

Excellent, thanks. I'll check it out. Much obliged to you both for
lending your expertise.

~A!

--
Anthony Levensalor
(e-mail address removed)

Only two things are infinite, the universe and human stupidity,
and I'm not sure about the former. - Albert Einstein
 
M

My Pet Programmer

Randy Webb said:
My Pet Programmer said the following on 12/28/2007 3:35 AM:
Randy Webb said:
[snippy-snip]
That is more for loading HTML that has script elements in it than
dealing with JSON.

I noticed that, and bookmarked it just in case it might come in handy
while I'm rewriting this horrible, awful, incredibly so bad that even I
know it sucks code from a certain offshore company.


--
Anthony Levensalor
(e-mail address removed)

Only two things are infinite, the universe and human stupidity,
and I'm not sure about the former. - Albert Einstein
 
M

My Pet Programmer

-Lost said:
In what situation does pure JSON need to be eval'd?
I know you were talking to David, but I'm talking about the stuff that
comes out of PHP's json_encode function, which is pure JSON, it just
comes back dynamically at runtime, and so would just be a string unless
eval'd.

So this would work, if I hard-coded it:
[
{"title":"Head Rush AJAX", "Category":"Computers"},
{"title":"Salem's Lot","Category":"Suspense\/Horror"},
{"title":"AAArrrgh, Volume 3", "Category":"Javascript"}
]

but it won't work like this:

var str = '[{"title":"Head Rush AJAX",
"Category":"Computers"},{"title":"Salem's
Lot","Category":"Suspense\/Horror"},{"title":"AAArrrgh, Volume 3",
"Category":"Javascript"}]';

Which is how it comes back from the server. Eval'ing it makes it real to
the client side. Because it's in a string var, it's not code until I eval.

All the best,
~A!

--
Anthony Levensalor
(e-mail address removed)

Only two things are infinite, the universe and human stupidity,
and I'm not sure about the former. - Albert Einstein
 
M

My Pet Programmer

-Lost said:
Response to My Pet Programmer <[email protected]>:
Basically named arrays become parent Objects and "anonymous" arrays
become Array literals in JavaScript.

I've never had to eval any JSON output from PHP, but I've never not
named sub-arrays. *shrugs*
Actually, that makes sense. I was not aware that if I named the arrays
it would "just work". And I'll be damned, you're right. I just tested
it. Thanks a million for that!

~A!

--
Anthony Levensalor
(e-mail address removed)

Only two things are infinite, the universe and human stupidity,
and I'm not sure about the former. - Albert Einstein
 
R

Richard Cornford

David said:
Don't believe most of what you read. Never use eval unless
its use is appropriate. Evaluating JSON data is an
appropriate use. Just don't do it if the data comes from
somebody else's server.
<snip>

That is a bit of an over simplification. While it would be a bad idea
to - eval - anything originating on someone else's server (or even
import a JS resource from someone else's sever in a SCRIPT element (at
least without the sort of absolute trust in that third party that is
difficult to justify)) it is not necessarily a good idea to just trust
anything originating on your own servers. Specifically, if a JSON
response was incautiously built on the server such that it took some
character sequence from some location (database or the like) and just
inserted it into a data context in a JSON response prior to broadcasting
it (i.e. just placed the character sequence between the quote marks of a
piece of string data in the JSON response), then there is a potential
script insertion vulnerability. This may be the case with a JSON
response that reflected back data that a user has input, or in
circumstances where a disgruntled/dishonest employee had the ability to
alter the contents of the database.

In reality it is only safe to - eval - a JSON response (even from your
own server) into an object structure on the client if you know either
that the JSON is guaranteed to have a particular predefined
form/structure and/or that any data inserted into it is/has been
properly escaped for the JSON data context, so that there is no chance
that any of its contents will be treated as executable source code. This
is best guaranteed by knowing that the software that builds the JSON
response always (and unconditionally) carries out a proper escaping
process at the point of building the response. Inevitably that means an
overhead for the server in building the responses (as most actual data
will probably not need any active modification at that point).

An illustration (in order to make sure that any future reader of this is
in no doubt about what I am talking about):-

Suppose a client is expecting a JSON response along the lines of:-

[
{
"quanity":5,
"name":"Widget",
"unitPrice":"12.25",
"description":"something about what a Widget is"
},
{
"quanity":2,
"name":"Widget2",
"unitPrice":"5.14",
"description":"something about what a Widget2 is"
}
]

- it can - eval - that into a structure of objects. The database
contains a 'description' field that is inserted into the JSON response
as it is being built. The expected contents of such a field might be the
character sequence:-

Something about what a Widget is

- but suppose what the database actually contained was the character
sequence (assume no line breaks):-

Something about what a Widget is","evil":(function(){/*code that adds an
arbitrary SCRIPT element into the DOM and so imports a JS resource from
a (dubious) third party server */})(),"evil2":"

- If this were inserted between the quotes of the 'description' string
the first quote in the data would terminate the description string, the
next section of the character sequence would add an 'evil' property to
the object structure and than define the inline execution of a function
expression to provide the value for that property, and the rest of the
characters add an 'evil2' property with an empty string value (that last
property is to take account of the final quote mark that was originally
intended to terminate the 'description' string. Now the JSON structure
being imported is the equivalent of:-

[
{
"quanity":5,
"name":"Widget",
"unitPrice":"12.25",
"description":"Something about what a Widget is",
"evil":(function(){
/*code that adds an arbitrary SCRIPT element into the DOM
and so imports a JS resource from a (dubious) third party
server */
})(),
"evil2":""
},
{
"quanity":2,
"name":"Widget2",
"unitPrice":"5.14",
"description":"Something about what a Widget2 is"
}
]

- and if you - eval - it your client's browser will import a third party
script that can do anything at all (including (but far from limited to)
monitoring and broadcasting every user key press).

Now that 'description' field's contents came from somewhere. It may have
been entered by a dishonest employee, or it may have been entered by a
remote 'user' of some sort, but either way it should not have been
trusted to be 'safe'.

Escaping a sequence of characters for use in a JSON string context
involves going through the string and replacing some characters with
escape sequences (placing a backslash before them or replacing them with
Hex or Unicode escape sequences). If that is done during the process of
building the JSON response the outcome might resemble:-

[
{
"quanity":5,
"name":"Widget",
"unitPrice":"12.25",
"description":"Something about what a Widget
is\u0022,\u0022evil\u0022:(function(){/* ...
*/})(),\u0022evil2\u0022:\u0022"
},
{
"quanity":2,
"name":"Widget2",
"unitPrice":"5.14",
"description":"Something about what a Widget2 is"
}
]

- and - eval -ing that will not have any side effects as that
'description' string is once again just a sequence of characters.

(So the next script insertion issue is with what the client-side script
does with the 'description' field, but that has nothing to do with
whether it is 'safe' to - eval - a JSON response.)

Richard.
 
M

My Pet Programmer

Richard Cornford said:
[snip]
(So the next script insertion issue is with what the client-side script
does with the 'description' field, but that has nothing to do with
whether it is 'safe' to - eval - a JSON response.)

Wow, thank you, Richard. I appreciate you taking the time to write that
out for us. That's awesome stuff. I'll definitely put some things in
place on the server to make sure my local stuff stays safe.

~A!


--
Anthony Levensalor
(e-mail address removed)

Only two things are infinite, the universe and human stupidity,
and I'm not sure about the former. - Albert Einstein
 
T

Thomas 'PointedEars' Lahn

-Lost said:
In what situation does pure JSON need to be eval'd?

Pardon? JSON is the JavaScript Object Notation, a data interchange format.
Name an instance where it would *not* be used to create a JS object from
the transferred data. Using the built-in eval() method to do just that
appears only natural to me, observing the usual caveats.

http://en.wikipedia.org/wiki/JSON


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message said:
Anything that says "never, ever use eval" is just as bad as using eval
when you don't need to.
Yes.

The rule of thumb is "Don't use eval for anything other than its
intended purpose".

Well, valid uses may appear that were not originally foreseen. One
should never use it when the languages (e.g. JS + HTML) provide a safer,
and maybe a simpler, alternative.
The purpose of eval is to evaluate code "not known at runtime".

That is unmitigated nonsense, probably misquoted from something more
carefully written. How can unknown code be evaluated? Even the output
of a random-code generator will be known, though in this case not by a
person, before it can be used.

The (apparent) purpose of eval is to evaluate code which cannot be known
at the time of authoring the code in which the eval occurs.

See FAQ 4.40 :-
4.40 When should I use eval?
The eval() function should only be used when it is necessary to evaluate
a string supplied or composed at run-time; the string can be anything
from a simple (but unpredictable) expression such as 12*2.54 to a
substantial piece of javascript code.

But I'd now suggest changing "composed" to the less anthropocentric
"constructed"; and possibly mentioning eval of trusted JSON as sound.
 
D

Dr J R Stockton

In comp.lang.javascript message said:
While you could make an argument for that, it is not always true. Most
JSON is known at the time the code is authored. People tend to use eval
simply because of ease and the lack of knowing how to do it any other
way.

Since you do not see the distinction between the "purpose of eval" and
the intent of any particular use (by the ignorant), there's no point in
discussing it with you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,740
Latest member
AdolphBig6

Latest Threads

Top