Using XMLHttpRequest without 'eval'
|
|
Thread rating:  |
My Pet Programmer - 28 Dec 2007 01:58 GMT 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!
 Signature Anthony Levensalor anthony@mypetprogrammer.com
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein
David Mark - 28 Dec 2007 02:09 GMT On Dec 27, 8:58 pm, My Pet Programmer <anth...@mypetprogrammer.com> wrote:
> The way I usually set up and work with the XMLHttpRequest to execute > server side functions and get results is this: [quoted text clipped - 14 lines] > (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.
My Pet Programmer - 28 Dec 2007 02:16 GMT David Mark said:
> On Dec 27, 8:58 pm, My Pet Programmer <anth...@mypetprogrammer.com> [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!
 Signature Anthony Levensalor anthony@mypetprogrammer.com
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein
-Lost - 28 Dec 2007 13:23 GMT Response to David Mark <dmark.cinsoft@gmail.com>:
> 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. In what situation does pure JSON need to be eval'd?
 Signature -Lost Remove the extra words to reply by e-mail. Don't e-mail me. I am kidding. No I am not.
My Pet Programmer - 28 Dec 2007 13:37 GMT -Lost said:
> Response to David Mark <dmark.cinsoft@gmail.com>: > [quoted text clipped - 3 lines] > > 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!
 Signature Anthony Levensalor anthony@mypetprogrammer.com
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein
-Lost - 28 Dec 2007 14:58 GMT Response to My Pet Programmer <anthony@mypetprogrammer.com>:
> var str = '[{"title":"Head Rush AJAX", > "Category":"Computers"},{"title":"Salem's [quoted text clipped - 4 lines] > real to the client side. Because it's in a string var, it's not > code until I eval. Ah, OK. You know that depends on how you compose your PHP arrays though, right?
For example, you must have used something like:
$jsonArray = array( array('title' => 'Head Rush AJAX', 'Category' => 'Computers'), array('title' => 'Salem\'s Lot', 'Category' => 'Suspense/Horror'), array('title' => 'AAArrrgh, Volume 3', 'Category' => 'JavaScript') );
Which yields: [{"title":"Head Rush AJAX","Category":"Computers"},{"title":"Salem's Lot","Category":"Suspense\/Horror"},{"title":"AAArrrgh, Volume 3","Category":"JavaScript"}];
Like you said. However...
$jsonArray = array( 'root' => array('title' => 'Head Rush AJAX', 'Category' => 'Computers') );
Yields:
{"root":{"title":"Head Rush AJAX", "Category": "Computers"}}
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*
 Signature -Lost Remove the extra words to reply by e-mail. Don't e-mail me. I am kidding. No I am not.
My Pet Programmer - 28 Dec 2007 15:06 GMT -Lost said:
> Response to My Pet Programmer <anthony@mypetprogrammer.com>:
> 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!
 Signature Anthony Levensalor anthony@mypetprogrammer.com
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein
Thomas 'PointedEars' Lahn - 28 Dec 2007 19:09 GMT > Response to David Mark <dmark.cinsoft@gmail.com>: >> 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. > > 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
 Signature var bugRiddenCrashPronePieceOfJunk = ( navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1 ) // Plone, register_function.js:16
Richard Cornford - 28 Dec 2007 18:18 GMT > David Mark wrote: >> My Pet Programmer wrote: [quoted text clipped - 9 lines] > 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.
My Pet Programmer - 28 Dec 2007 18:59 GMT 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!
 Signature Anthony Levensalor anthony@mypetprogrammer.com
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein
Randy Webb - 28 Dec 2007 08:17 GMT My Pet Programmer said the following on 12/27/2007 8:58 PM:
> The way I usually set up and work with the XMLHttpRequest to execute > server side functions and get results is this: [quoted text clipped - 14 lines] > (The above is a highly snipped version without any of the usual checks > and balances, it's for illustration only) What type of data is someurl returning?
> What I'm curious about is how to get the data back and get it read with > using eval(). 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.
> 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. 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".
> Do one of you guys have any links/advice/vitriol I could use to get my > head around a better way? 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.lang.javascript/browse_thread/thread/415949d 1bcce6e6a/96dd313cb56fb75f?lnk=gst&q=loadhtmlfragment#96dd313cb56fb75f>
Has the latest posted version that I have written of it.
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
My Pet Programmer - 28 Dec 2007 08:35 GMT 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.lang.javascript/browse_thread/thread/415949d 1bcce6e6a/96dd313cb56fb75f?lnk=gst&q=loadhtmlfragment#96dd313cb56fb75f> Excellent, thanks. I'll check it out. Much obliged to you both for lending your expertise.
~A!
 Signature Anthony Levensalor anthony@mypetprogrammer.com
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein
Randy Webb - 28 Dec 2007 08:46 GMT My Pet Programmer said the following on 12/28/2007 3:35 AM:
> Randy Webb said: >> My Pet Programmer said the following on 12/27/2007 8:58 PM: [quoted text clipped - 12 lines] > 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. Then eval it. Just beware of potential scope issues and you won't have a problem with it.
>> [snip] >> Anything that says "never, ever use eval" is just as bad as using eval [quoted text clipped - 11 lines] > Excellent, thanks. I'll check it out. Much obliged to you both for > lending your expertise. That is more for loading HTML that has script elements in it than dealing with JSON.
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
My Pet Programmer - 28 Dec 2007 09:14 GMT 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.
 Signature Anthony Levensalor anthony@mypetprogrammer.com
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein
Dr J R Stockton - 30 Dec 2007 16:05 GMT >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.
 Signature (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME. <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links; <URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ; <URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.
Randy Webb - 31 Dec 2007 01:01 GMT Dr J R Stockton said the following on 12/30/2007 11:05 AM:
>> Anything that says "never, ever use eval" is just as bad as using eval >> when you don't need to. [quoted text clipped - 7 lines] > should never use it when the languages (e.g. JS + HTML) provide a safer, > and maybe a simpler, alternative. And that alternative exists for JSON.
>> 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. I would try to satisfy your pedanticism but I won't.
> 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? [quoted text clipped - 5 lines] > But I'd now suggest changing "composed" to the less anthropocentric > "constructed"; and possibly mentioning eval of trusted JSON as sound.
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/ Answer:It destroys the order of the conversation Question: Why? Answer: Top-Posting. Question: Whats the most annoying thing on Usenet?
Randy Webb - 31 Dec 2007 01:05 GMT Dr J R Stockton said the following on 12/30/2007 11:05 AM:
>> Anything that says "never, ever use eval" is just as bad as using eval >> when you don't need to. [quoted text clipped - 7 lines] > should never use it when the languages (e.g. JS + HTML) provide a safer, > and maybe a simpler, alternative. And that alternative exists for JSON.
>> 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. I would try to satisfy your pedantic desires but I won't waste the time.
> 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. 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.
> See FAQ 4.40 :- > 4.40 When should I use eval? [quoted text clipped - 5 lines] > But I'd now suggest changing "composed" to the less anthropocentric > "constructed"; and possibly mentioning eval of trusted JSON as sound. <URL: http://jibbering.com/faq/index.html#FAQ5_2>
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Dr J R Stockton - 31 Dec 2007 19:34 GMT >> 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. [quoted text clipped - 3 lines] >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.
 Signature (c) John Stockton, Surrey, UK. ???@merlyn.demon.co.uk Turnpike v6.05 MIME. Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Food expiry ambiguities: <URL:http://www.merlyn.demon.co.uk/date2k-3.htm#Food>
|
|
|