Why not eval() JSON? - javascript

As far as I know it is considered bad practice to eval() JSON objects in JavaScript, because of security. I can understand this concern if the JSON comes from another server.
But if the JSON is provided by my own server and is created using PHP's json_encode (let us assume it is not buggy), is it legitimate to simply use eval() to read the JSON in JS or are there any security problem I currently can't think of?
I really don't want to deal with dynamically loading a JSON parser and would be glad to simply use eval().
PS: I will obviously use the native JSON object if it is available, but want to fall back to eval() for IE/Opera.

In your scenario, the question becomes, where is PHP getting the javascript to execute from? Is that channel secure, and free from potential user manipulation? What if you don't control that channel directly?

There are a number of ways that your security may be compromised.
Man in the middle attacks could theoretically alter the contents of data being delivered to the client.
Your server traffic could be intercepted elsewhere and different content could be provided (not quite the same as a MIM attack)
Your server could be compromised and the data source could be tampered with.
and these are just the simple examples. XSS is nasty.
"an ounce of prevention is worth a pound of cure"

Besides the obvious security issues:
Native JSON is faster
You don't need to "load" a JSON parser it's just another function call to the JavaScript engine

Tip:
in asp.net using JSON is considered bad becuase parsing of DateTime differs between the server and the client so we use a special function to deserialize the date in javascript. I'm not sure if PHP has the same issue but its worth mentioning though.

check out this:http://blog.mozilla.com/webdev/2009/02/12/native-json-in-firefox-31/
so at least for firefox you can use the built in json parser

Seriously? Some of the guys here are paranoid. If you're delivering the JSON and you know it's safe, it's ok to fallback(*) to eval(); instead of a js lib for IE. After all, IE users have much more to worry about.
And the man-in-the-middle argument is bullsh*t.
(*) the words fallback and safe are in bold because some people here didn't see them.

Related

XSS potential in a JavaScript variable assignment

Background
I'm trying to better understand potential XSS attack scenarios. I understand if you are retrieving data component 'unknow_data' from a server and not validating it the following scenarios could allow malicious code to run.
<script src = unknow_data >
or
<a href=unknow_data></a>
Where unknow_data could be 'javascript:somethingMalicious' instead of pure data.
Question
Is there any threat of XSS when passing unknown data directly into a JavaScript object and not a script tag or html attribute? For example:
var G = unknow_data;
What javascript code, if any, would have to be injected into a plain javascript object for it to be a security risk? My thinking so far is that this is only a threat if you are calling
eval(G)
Is my understanding correct?
It would definitely be a security hole.
Example, the unknown_data could be 1; alert('xss').
However, if you JSON encoded it using your server-side language, it would be safe to print it there (however it may have encoded attacks in it - deal with it like you normally would depending on its context).
It depends on what you do with G.
Certainly eval-ing it would be problematic, but why would you do that anyway?
In addition to the attack mentioned by #alex, if you insert in into the DOM in one way or another, then that's another attack surface.
You should HTML-escape it before inserting it into the DOM, either on the server or the client. If you are using a templating language like Handlebars, then {{G}} will take care of the HTML escaping for you. You need to be cautious with the triple-mustache ({{{G}}}), which skips the HTML escaping.

encrypting data on client-side via html5 javascript

im building a web app in html5.. basically a form with a time counter and questions and answers.
im looking for a way that the user cannot change the score (that is calculated from the time took to answer the question) via browser debugger or etc.
encrypting the raw data sounds like an options.. but when the data is at dom, the user can change it.
i added some "time checking" in server side.. but still i would prefer some client side protection as well.
any suggestions? thanks
I'm no web pro, but I'd say just stick all the validation on the server side. From what I know about people exploiting MMORPGs, there is always a way to access/change client side data.
What you're asking for is impossible. No matter how you implement it, the user can use debugging tools to alter how the code runs in their browser - or, ultimately, just generate the HTTP POST request themselves, independent of your code.
Well, since you're saying you're using html5, why don't you just use the storage support?
e.g:
var store = sessionStorage.question= new Array();
store[0]="10s";
store[1]="5s";
Now just set that programmatically! It will last for the whole session
Put that in a file and import it and the better-than-average user wont know where to look!
You can also check This Link for a more robust solution
As Nick says, a determined user will be able to get round any encryption scheme you use on the client machine. At most you can make it difficult for them to break. You need to do two things, 1) encrypt so as to make tampering difficult and 2) try to detect any tampering that does occur.
I don't know what is available off the shelf for Javascript, if available then use AES for encryption and HMAC to detect tampering. If you have to write your own then use RC4 for encryption (not as strong as AES but much simpler to code) and a checksum to detect tampering.
One thing you can do to make it more difficult for an attacker to find your encryption key and HMAC key is not to store them in one place. Have two arrays such that the real key is array1 XOR array2. That way the actual key is not explicitly in code anywhere.

Injecting javascript in JSON and security

I have an online service where users can create json-backed documents. These are then stored on a server and other users can load them. The json is then decoded exactly as it was submitted. Are there any security risks in the event that a user tampers with the json before they submit it and injects arbitrary javascript, which is then executed on the viewers' browser? Is this even possible? that's what I need to know, if this is possible, or arbitrary execution of javascript from a json string is possible.
This depends entirely on a) whether you're scrubbing the JSON on the server side, and (even more) on b) how you're decoding the JSON on the client side when you load it again.
Any code that uses eval() to deserialize the JSON into a Javascript object is open to exactly the attack you describe.
Any code that uses JSONP to load the JSON (i.e. passing the JSON as a Javascript literal to a named callback function) is open to the attack you describe (it's effectively the same as using eval()).
Most robust JSON-parsing mechanisms (e.g. json2.js, the jQuery $.parseJSON function, or native JSON.parse() functions in browsers that support it) will not accept JSON that doesn't follow the JSON specification. So if you're using a library to parse the JSON string, you may be safe.
No matter how you intend to load the JSON on the client side, it is good practice to scrub any user-submitted content on the server side. In this case, you might use server-side code to check that the JSON is valid (e.g. using json.loads(user_submitted_json) in Python, and catching errors).
So with some care on both the server side and the client side, you should be able to do this safely.
<plug shameless="true">
JSON sans eval is designed to avoid problems with malformed JSON while still being efficient at parsing.
This JSON parser does not attempt to validate the JSON, so may return a result given a syntactically invalid input, but does not use eval so is deterministic and is guaranteed not to modify any object other than its return value.
There are a number of JSON parsers in JavaScript at json.org. This implementation should be used whenever security is a concern (when JSON may come from an untrusted source), speed is a concern, and erroring on malformed JSON is not a concern.
</plug>
JSON has traditionally been parsed using an eval() statement, which is about as insecure as it is possible to get. If you allow this, your application will be insecure.

How to simply encode and decode a string variable

I need to simply encode a string variable (my api key) so that is not easily readable by human eyes, I need it to easily decode back to exactly the same initial string. What is the standard practical and fast (less computing on the user side) way to do this?
Many thanks in advance!
If it doesn't have to be super-secure, Base64 encoding is always handy:
http://www.webtoolkit.info/javascript-base64.html
Everything you can do to obfuscate information on the client implies that you include the code for de-obfuscation right next to it.
So… apart from adding one extra step for your program (and the hypothetical attacker), you gain nothing. Well, not much anyway.
If your API key is secret, keep it on the server and let the server do the work through HTTP requests.
You could try a Javascript Obfuscator to either encode your whole script or parts. Not an absolute solution but a start to protecting your code.
you could use a 3rd party base64 encoder library: http://ostermiller.org/utils/Base64.html
Is this secret information or not?
If it is secret, you need a real encryption library and some deep thinking too make sure your secret is kept secret. I would seriously consider never sending any secret to the browser.
If this isn't secret and you just need need to send this over the URL without it getting borked then escape()/unescape() are what you are looking for.

Why is JSON important?

I've only recently heard about JSON (Javascript Object Notation).
Can anybody explain why it is considered (by some websites/blogs/etc) to be important?
We already have XML, why is JSON better (apart from being 'native to Javascript')?
Edit: Hmm, the main answer theme seems to be 'it is smaller'. However, the fact that it allows data fetching across domains, seems important to me. Or is this in practice not (yet) much used?
XML has several drawbacks:
It's heavy!
It provides a hierarchical representation of content which is not exactly the same as (but pretty much similar to) Javascript object model.
Javascript is available everywhere. Without any external parsers, you can process JSONs directly with JS interpreter.
Clearly it's not meant to replace XML completely. For JS based Web apps, its advantages can be useful.
JSON is generally much smaller than its XML equivalent. Smaller transfer means faster transfer, which results in a better user experience.
JSON is much more concise. XML:
<person>
<name>John Doe</name>
<tags>
<tag>friend</tag>
<tag>male</tag>
</tags>
</person>
JSON:
{"name": "John Doe", "tags": ["friend", "male"]}
There's fewer overlapping features, too. For example, in XML there's tension between choosing to use elements (as above), versus attributes (<person name="John Doe">).
JSON came into popular use primarily because it offers a way to circumvent the same-origin policy used in web browsers and thereby allow mashups.
Let's say you're writing a web service on domain A. You can't load XML data from domain B and parse it because the only way to do that would be XMLHttpRequest, and XMLHttpRequest was originally limited by the same-origin policy to talking to only URLs at the same domain as the containing page.
It turns out that for a variety of reasons, you are allowed to request <script> tags across origins. Clever people realized this was a good way to work around the limitation with XMLHttpRequest. Instead of the server returning XML, it can return a series of JavaScript object and array literals.
(bonus question left as an exercise to the reader: why is <script src="..."> allowed across domains without server opt-in but XHR isn't?)
Of course, returning a <script> which consists of nothing more than object literals is not useful because without assigning the values to some variable, you can't do anything with it. Thus, most services use a variant of JSON, called JSONP (http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/).
With the rise in popularity of mashups, people realized that JSON was a convenient data interchange format in general, especially when JavaScript is one end of the channel. For example, JSON is used extensively in Chromium, even in cases where C++ is on both sides. It's just a nice lightweight way to represent simple data, that good parsers exist for in many languages.
Amusingly, using <script> tags to do mashups is incredibly insecure because it is essentially XSS'ing yourself on purpose. So native JSON (http://ejohn.org/blog/native-json-support-is-required/) had to be introduced, which obviates the original benefits of the format. But by that time, it was already super popular :)
If you are working in Javascript, it is much easier to us JSON. This is because JSON can be directly evaluated into a Javascript object, which is much easier to work with than the DOM.
Borrowing and slightly altering the XML and JSON from above
XML:
<person>
<name>John Doe</name>
<tag>friend</tag>
<tag>male</tag>
</person>
JSON:
{ person: {"name": "John Doe", "tag": ["friend", "male"]} }
If you wanted to get the second tag object with XML, you'd need to use the powerful but verbose DOM apis:
var tag2=xmlObj.getElementsByTagName("person")[0].getElementsByTagName("tag")[1];
Whereas with a Javascript object that came in via JSON, you could simply use:
var tag2=jsonObj.person.tag[1];
Of course, Jquery makes the DOM example much simpler:
var tag2=$("person tag",xmlObj).get(1);
However, JSON just "fits" in a Javascript world. If you work with it for a while, you will find that you have much less mental overhead than involving XML based data.
All the above examples ignore the possibility that one or more nodes are available, duplicated, or the possibility that the node has just one or no children. However, to illustrate the native-ness of JSON, to do this with the jsonObj, you'd just have to:
var tag2=(jsonObj.person && jsonObj.person.tags && jsonObj.person.tags.sort && jsonObj.person.tags.length==2 ? jsonObj.person.tags[1] : null);
(some people might not like that long of ternary, but it works). But XML would be (in my opinion) nastier (I don't think you'd want to go the ternary approach because you'd keep calling the dom methods which may have to do the work over again depending on implementation):
var tag2=null;
var persons=xmlObj.getElementsByTagName("person");
if(persons.length==1) {
var tags=persons[0].getElementsByTagName("tag");
if(tags.length==2) { tag2=tags[1]; }
}
Jquery (untested):
var tag2=$("person:only-child tag:nth-child(1)",xmlObj).get(0);
These web pages may help:
JSON - The Fat Free alternative to xml
Why JSON is Important to You!
It depends on what you are going to do. There are a lot of answers here that prefer JSON over XML. If you take a deeper look there isn't a big difference.
If you have a tree of objects you get only tree of javascript objects back. If you take a look at the tension to use OOP style access than turns back on you. Assume you have an object of type A, B ,C that are constructed in a tree. You can easily enable them to be serialzed to JSON. If you read them back in you only get a tree of javascript objects. To reconstruct your A, B, C you have to stuff the values manually into manually created objects or you doing some hacks. Sound like parsing XML and creating objects? Well, yes :)
This days only the newest browsers come with native support for JSON. To support more browsers you have two options: a) you load a json paraser in javascript that helps you parsing. So, how fat does this sound regarding fatreeness? The other option as I often see is eval. You can just do eval() on a JSON String to get the objects. But that introduces a whole new set of security problems. JSON is specified so it can't contain functions. If you are not checking the objects for function someone can easily send you code that is being executed.
So it might depend on what you like more: JSON or XML. The biggest difference is propably the ways of accessing things, be it script tags XMLHTTPRequest... I would decide upon this what to use. In my opinion if there would be proper support for XPATH in the browsers I would often decide for XML to use. But the fashion is directed towards json and loading additional json parsers in javascript.
If you can't decide and you know you need something really powerful you ight have to take a look at YAML. Reading about YAML is very interesting to get more insight in the topic. But it really depends on what you are trying to do.
JSON is a way to serialize data in Javascript objects. The syntax is taken from the language, so it should be familiar to the developer dealing with Javascript, and -- being the stringification of an object -- it's a more-natural serialization method for interaction within the browser than a full-fledged XML derivative (with all the arbitrary design decisions that implies).
It's light and intuitive.
JSON's a text-based object serialization format that's more lightweight than XML and that directly integrates with JavaScript's object model. That's most of its advantages right there.
Its disadvantages (compared to XML) are, roughly: fewer available tools (forget about standard validation and/or transformation, to say nothing of syntax highlighting or well-formedness checking in most editors), less likely to be human-readable (there's huge variations in the readability of both JSON and XML, so that's a necessarily fuzzy statement), tight integration with JavaScript makes for not-so-tight integration with other environments.
It's not that it is better, but that it can tie many things together to allow seamless data transfer without manual parsing!
For example javascript -> C# web service -> javascript

Categories

Resources