javascript eval on php json_encode output - security concerns - javascript

Here is a quick example of something I was wondering about, before we start I am aware that eval should only be used when absolutely needed.
Let's say I have an endpoint that runs some code like this:
endpoint.php
<?php
$input = sanitised($_POST['someData']);
$array = someDatabaseQueryMethod($input);
echo 'runtime.getItem("'.A_SAFE_DEFINED_CONSTANT.'").stateChange({"newValues":'.json_encode($array).'});';
?>
then I have an index.php that looks like this:
... ommitted...
<body>
$.ajax({
url : "./endpoint.php",
type: "POST",
data : {someData: 1},
success: function(data, textStatus, jqXHR)
{
eval(data);
},
error: function (jqXHR, textStatus, errorThrown)
{
//error logic here
}
});
...
Is there a situation that can occur where some content in $array (which, lets say, could contain anything at all, multi dimensional, loads of different strings / other data types, but will always be a valid array that won't cause json_encode to fail) could mean that the eval statement could be vulnerable to some kind of injection?
Effectively I always want .stateChange to recieve an object that it can take a look at and decide what to do in this example
I know this might seem like quite a convoluted example, it is taken out of context - this is the smallest verifiable example i could come up with.
EDIT: while the above is closes to what I am doing, i guess the smallest example would actually be this:
endpoint.php
<?php
$input = sanitised($_POST['someData']);
$array = someDatabaseQueryMethod($input);
echo 'var a = '.json_encode($array).';';
?>
OK guys i get it - no need for more comments that do not answer the question which is not about different methods of doing the same thing but thanks for your feedback
It would be great to get an example of where this would break, not hearsay about how bad eval is.

Is there a situation that can occur where some content in $array
(which, lets say, could contain anything at all, multi dimensional,
loads of different strings / other data types, but will always be a
valid array that won't cause json_encode to fail) could mean that the
eval statement could be vulnerable to some kind of injection?
Yes, absolutely! If I were a hacker, I could very likely find a way to hijack a user's entire session if there's ever even the slightest mistake made in escaping user strings. There is absolutely no reason you should need to take that kind of risk. Use JSON.parse(str) instead. Since you're currently returning JavaScript code, change it to simply return your value as an object with two values that you automatically do two things with. (eg: {stateChangeTarget: 'CONSTANT_IDENTIFIER', stateChangeData: {"newValues": [...]} }) This will give you the array that you want. Then perform the expected functions in the result like this:
dataType: "json"
success: function(data)
{
runtime.getItem(data.stateChangeTarget).stateChange(data.stateChangeData);
},
This is also extensible to other client applications. If you decide to write a mobile app, that app won't be able to run JavaScript, and so it'll be lost when the server returns a pure JavaScript command with no neutral way to access the data (JSON)

Related

How do I properly use the json ajax

I want to send data from php to a browser using JSON. I think I understand the process - see my example code below. But someone told me this is not the right way to do it. I have been researching for three days but because my English is poor I am not confident that I have found an answer.
What I am hoping for is a sample of code that will receive the JSON and pour it into html elements such as a div, and give it style via CSS, etc.
I really just want an example of how to do this so that I can learn from it and expand it myself for my own needs, but I am unconfident that this approach is correct and do not want to write more bad code.
Thanks
Javascript
$(document).ready(function() {
$.ajax({
type : 'POST',
url : 'server.php',
dataType:"json",
success : function (data) {
$("#orders").html(JSON.stringify(data));
}
});
});
PHP
<?php
$db = new PDO('mysql:host=localhost;dbname=Contact', 'root', '');
$statement=$db->prepare("SELECT * FROM myfeilds");
$statement->execute();
$results=$statement->fetchAll(PDO::FETCH_ASSOC);
$json=json_encode($results);
echo $json;
?>
You don't need to call JSON.stringify on the data that gets returned in your response. This method is for converting a javascript object to a JSON string, but your PHP code should be sending a JSON string back already by the looks of it.
So it depends on what your returned JSON looks like, but usually it'll be something like this:
{"name":"Mike", "phone":"5551234", ...} etc
So in your success callback, you would do something like this:
$("#name").text(data.name);
$("#phone").text(data.phone);
And so on.
Note that I'm using the .text() method. You could use .html() as you've done but you probably don't need to unless your JSON strings contain HTML or you want to write out HTML like so:
$("#name").html("<p>" + data.name + "</p>");
As for styling, I would setup your styles in advance so that you don't have to do it in javascript as this will be more performant.
However, if for some reason you needed to then you could do something like:
$("#name").css({"display":block","color": "#000"});
Hope that helps.

Get contents of web page and place in array or string

I am not really sure how to phrase this question, so I will just ask the best I can.
I would like to know how to grab the contents of a webpage and place it in a string or array so I can parse the data.
This is the webpage: https://campusdata.uark.edu/api/buses?callback=?&routeIds=8
The webpage returns something like this:
?([{"id":25,"fleet":15,"name":"Fleet 15","description":"","zonarId":9,"gpsId":"8061088","latitude":"36.0680039","longitude":"-94.1758039","speed":0.000,"heading":89.700,"power":true,"date":"\/Date(1456339080000)\/","color":"#0090ff","routeName":"Blue","routeId":8,"distance":9999999999,"nextStop":"Garland Center","nextArrival":"8 mins"},{"id":33,"fleet":6,"name":"Fleet 6 ","description":"","zonarId":13,"gpsId":"8061090","latitude":"36.0818423","longitude":"-94.1707598","speed":0.000,"heading":181.700,"power":true,"date":"\/Date(1456339200000)\/","color":"#0090ff","routeName":"Blue","routeId":8,"distance":2.31887983012931,"nextStop":"South Creekside","nextArrival":"1 mins"}]);
I am not sure the best way to go about this... AJAX through JQuery? Maybe a php call? I don't know.
I have searched for this, but like I said, I don't know exactly how to phrase the question, so my search results have been sporadic at best.
Can someone help me please?
Seems like a JSONP call. You can use jQuery to easily fetch the data from the API end point. Please see the example below:
$.ajax({
url: "https://campusdata.uark.edu/api/buses?callback=?&routeIds=8",
// The name of the callback parameter
jsonp: "callback",
// Tell jQuery we're expecting JSONP
dataType: "jsonp",
data: {},
// Work with the response
success: function( response ) {
console.log( response ); // server response
}
});
Here is a jsfiddle with working example.
Please make sure to include jquery in the page before trying this.
Your can use this in PHP
$site = file_get_contents("http://campusdata.uark.edu/api/buses?callback=&routeIds=8");
print_r(json_decode($site));
Reference
json_encode
file_get_contents
Get the page content with file_get_contents function. Remove illegal character. Convert the json format to PHP array:
<?php
$page = file_get_contents('https://campusdata.uark.edu/api/buses?callback=?&routeIds=8');
$page = substr($page, 0, -2);
$page = substr($page, 2);
var_dump (json_decode($page));

multiple ajax calls is causing mixed datasets

I've been developing a phonegap application which uses jQuery Mobile for it's main structure.
When the site/app runs, it executes a number of ajax calls to get the latest data to the app. For example, a list of items is gathered for the homepage, whilst other lists of other items are gathered for other pages.
What I am finding is that every now and then there is a mixup in data.
As a random (but applicable) example:
Query 1 - get names and photos of people
Query 2 - get names and photos of cities/locations
In each of the ajax calls, instead of using (data, status) I have renamed the data object to a unique identifier hoping this would resolve the issue.
Then, on my $.each function I have ensured that the iterator has a different name too, so instead of (i, item) it might be (i, personitem) and (i, cityitem)
The Issue
Despite my best attempts to get this data to not have any possibility of crossover, I'm finding that (to keep with the current example) - photos of people will show up on the cities page, and photos of cities will show up on the users page.
This is also an intermittent issue. Sometimes it won't happen at all, other times it will happen a lot or only a little bit.
I hope I have explained myself clearly. Thank you in advanced to anyone willing to help! I'm all out of ideas :-(
==================
UPDATE
My main question is if anyone knows what might cause data-mixups in such queries.
My queries all look like this:
$.ajax({
url: 'get_cities.php?country='+country,
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(citydata, status){
if(citydata.length == 0){
$('#somediv').append('no data to show');
}
$.each(citydata, function(i,cityitem){
var content = '<img src="'+cityitem.image+'" />'
+'<p>'+cityitem.name+'</p>';
$('#somediv').append(content);
}
});
At this point I believe #mason81 was correct with his suggestion.
I removed all of the:
jsonp: 'jsoncallback',
in my code, and then updated my PHP files to use
echo $_GET['callback'] . '(' . json_encode($records) . ');';
instead of
echo $_GET['jsoncallback'] . '(' . json_encode($records) . ');';
I originally also placed &callback=? into my URL's but from reading the jQuery Ajax documentation it should automatically assign a random unique callback to each call as long as you are using dataType: jsonp without manually specifying a callback parameter.
If this fails I'll still consider this the correct answer, I'll probably just have to go through and either assign unique callback parameters to each request or ammend my URL's with &callback=? as mentioned above.
Thanks everyone for their input!

JSON external file vs defined in JS

What are some arguments as to when to use JSON external file such as with jQuery's
$.getJSON('external.json',function(data){});
(ajax retrieving) versus defining it in javascript with
var myJson = { "someVar": { "1": ["test1","test2"], "2": ["test3","test4"]} }
What is the "proper" way of doing it? Does it depend on JSON length or are there any other factors that can tell you what approach to use?
The way I see it: choose between loading another file which is supposed to be slow as you are loading data via ajax call or adding plenty of lines into already packed javascript file which is not a good thing either. Surely there must be some distinction as to where you should use one or another ... ?
I am not interested only in speed difference (getting file from ajax is of course slower) but also in other aspects such as what is generally used when and what should be used in some case ...
The first one is a shorthand for:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
This is an Ajax request which will take more time than having a simple JSON object into the file.
I would prefer the second one IF it's possible. Also if you attend to have good performances the first one is longer.
time( Loading+parsing 2 files ) >> time( Read a Javascript object )
If your data is known at page creation time you're probably best to use an object literal like:
var myJson = {...}
However, as Kursion mentions,
$.getJSON(...)
is a shorthand method for retrieving json data asynchronously via ajax. You'd use it if you want to retrieve data from the server that wasn't known at the time of page load...
For example, if a user enters a search term in an input control, you might want to retrieve JSON in response to that without performing a whole page update. You couldn't simply define a javascript object up-front because you wouldn't know what the search term was in advance.

How to pass variables from an HTTPObject

I'm very, very new to Javascript, and to web programming in general. I think that I'm misunderstanding something fundamental, but I've been unable to figure out what.
I have the following code:
function checkUserAuth(){
var userAuthHttpObject = new XMLHttpRequest();
var url = baseURL + "/userAuth";
userAuthHttpObject.open("POST",url,true);
userAuthHttpObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
userAuthHttpObject.onload=function(){
if (userAuthHttpObject.readyState == 4) {
var response = json.loads(userAuthHttpObject.responseText);
return response; //This is the part that doesn't work!
}
};
userAuthHttpObject.send(params);
}
I would love to call it from my page with something like:
var authResponse = checkUserAuth();
And then just do what I want with that data.
Returning a variable, however, just returns it to the userAuthObject, and not all the way back to the function that was originally called.
Is there a way to get the data out of the HttpObject, and into the page that called the function?
Working with AJAX requires wrapping your head around asynchronous behavior, which is different than other types of programming. Rather than returning values directly, you want to set up a callback function.
Create another JavaScript function which accepts the AJAX response as a parameter. This function, let's call it "takeAction(response)", should do whatever it needs to, perhaps print a failure message or set a value in a hidden field and submit a form, whatever.
then where you have "return response" put "takeAction(response)".
So now, takeAction will do whatever it was you would have done after you called "var authResponse = checkUserAuth();"
There are a couple of best practices you should start with before you continue to write the script you asked about
XMLHTTTPRequest() is not browser consistent. I would recommend you use a library such as mootools or the excellent jquery.ajax as a starting point. it easier to implement and works more consistently. http://api.jquery.com/jQuery.ajax/
content type is important. You will have have problems trying to parse json data if you used a form content type. use "application/json" if you want to use json.
true user authorization should be done on the server, never in the browser. I'm not sure how you are using this script, but I suggest you may want to reconsider.
Preliminaries out of the way, Here is one way I would get information from an ajax call into the page with jquery:
$.ajax({
//get an html chunk
url: 'ajax/test.html',
// do something with the html chunk
success: function(htmlData) {
//replace the content of <div id="auth">
$('#auth').html(htmlData);
//replace content of #auth with only the data in #message from
//the data we recieved in our ajax call
$('#auth').html( function() {
return $(htmlData).find('#message').text();
});
}
});

Categories