Very late to the game -
I've just now started to think about XSS on my website. Unfortunately, in several places I created objects that I pass via Ajax:
var params = {};
params.firstName = $("#firstName").val();
params.lastName = $("#lastName").val();
$.ajax({url:url, data:params}).done();
Anyone can write in executable JS. Now, from what I've read, I can easily remedy this situation by doing this:
var params = {};
params.firstName = encodeURIComponent($("#firstName").val());
params.lastName = encodeURIComponent($("#lastName").val());
$.ajax({url:url}, data:params).done();
But instead of going through every place I create an object and wrapping every field in encodeURIComponent --- is there any way to simply escape characters directly on the params instead of on each property?
Thanks for any helpful tips.
Update: When Content-Type:application/x-www-form-urlencoded; charset=UTF-8 then form data is automatically encoded.
Something like this would work:
function encodeParams(data) {
Object.keys(data).forEach(function(key) {
data[key] = encodeURIComponent(data[key]);
});
return data;
}
You could use like so:
var params = encodeParams({
firstName: $('firstName').val(),
lastName: $('lastName').val()
});
ajax(...)
Related
So I've been working on this project but I'm stuck because I can't figure out how I should go about setting the other values of this new JSON object. So basically on the front end I have this:
HTML page view. The 'cat4' ID is the new object I tried to create, and illustrates the error I'm trying to fix. The problem is that I'm having trouble setting the LIMIT value of newly created objects (or multiple values at all). Here is the code where the object is created:
function sendCat()
{
window.clearTimeout(timeoutID);
var newCat = document.getElementById("newCat").value
var lim = document.getElementById("limit").value
var data;
data = "cat=" + newCat + ", limit=" + lim;
var jData = JSON.stringify(data);
makeRec("POST", "/cats", 201, poller, data);
document.getElementById("newCat").value = "Name";
document.getElementById("limit").value = "0";
}
In particular I've been playing around with the line data = "cat=" + newCat + ", limit=" + lim; but no combination of things I try has worked so far. Is there a way I can modify this line so that when the data is sent it will work? I find it odd that the line of code works but only for setting one part of the object.
The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
MDN
I think this is what you want:
const newCat = 'Meow';
const newLimit = 5;
const data = {
cat: newCat,
limit: newLimit
}
console.log(JSON.stringify(data));
What you're referring to as a 'JSON object' is actually just a javascript object, you can make one using object literal syntax. An object literal with multiple properties looks like this:
var data = {
cat: newCat,
limit: lim
};
makeRec("POST", "/cats", 201, poller, JSON.stringify(data));
assuming the fifth parameter to makeRec is supposed to be the POST request body as stringified JSON, as your code seems to imply
In my webapp, I have a model with properties whose names are dynamically generated based on data from the server. For example, I would normally reference this by doing something like this from my controller:
var str1 = 'property.name.with.dots'; // String from server
this.get('model.someProperty')[str1].integer = 2;
this.get('model.someProperty')[str1].integer += 1;
But Ember doesn't like this - it says I should use a set or get function. Which makes sense. So I want to do something like this in place of the last line above:
this.get('model.someProperty.' + str1).incrementProperty('integer');
This would work fine out of the box if str1 didn't have dots. It does, though, so what can I do to get Ember's getters to work? I tried
this.get('model.someProperty')[str1].incrementProperty('integer');
but it doesn't work - the subobjects don't get Ember's methods by default.
Definitely
Massage the data before handing it off to Ember, having dots in your name will just cause a plethora of chaining problems.
Clean the data, I chose _ (this isn't deep cleaning, exercise for your fun)
App.cleanData = function(result){
var response = {},
re = new RegExp('\\.', 'g'),
newKey;
for(var key in result){
newKey = key.replace(re, '_');
response[newKey] = result[key];
}
return response;
};
Use the cleaned data instead of the server data
App.FooRoute = Em.Route.extend({
model: function(){
return $.getJSON('/foo').then(function(result){
return App.cleanData(result);
}
}
});
Here's how I'm initializing and building an array:
var newCountyInfo = new Object();
newCountyInfo.name = newCountyName;
newCountyInfo.state = newCountyState;
newCountyInfo.zips = newCountyZips;
newCountyInfo.branchID = newCountyBranchID;
So I have my four elements in the array. I'm then passing newCountyInfo to another function to pull out the elements for display in some HTML elements.
The only way I know how to get to the individual elements in the function that uses them is this:
JSON.parse(JSON.stringify(newCountyValidation)).name
JSON.parse(JSON.stringify(newCountyValidation)).state
... etc...
There's got to be a better/shorter/more elegant way of doing this!
What is it?
Why are you serializing at all? I don't understand what JSON has to do with this, unless you're using web workers, ajax, or something else which demands serialization. Start with object literal syntax:
var newCountyInfo = {
name: newCountyName,
state: newCountyState,
zips: newCountyZips,
branchID: newCountyBranchID
};
And just pass the whole object to the other function:
someOtherFunction(newCountyInfo);
Which can access the fields using plain old property accesses:
function someOtherFunction(foo) {
console.log(foo.name); // whatever was in newCountyname
}
No JSON whatsoever.
Something like this should work just fine:
var newCountyInfo = {
name: newCountyName,
state: newCountyState,
zips: newCountyZips,
branchID: newCountyBranchID
}
function test(newCountyValidation)
{
alert(newCountyValidation.name);
}
test(newCountyInfo);
I get data is undefined, i guess i can't ['productId'] in an array, but i think i need this structure in the json, i tried a couple of variation but it never was, what i needed
i just want to send a json via ajax.
jQuery(':checked').each(function(i){
data[i]['productId'] = jQuery(this).parent().find('.productId').val();
jQuery(this).parent().find('.attrGrp').each(function(j){
data[i]['attrGrps'][j]['uid'] = jQuery(this).find('.active').attr('id');
data[i]['attrGrps'][j]['amount'] = jQuery(this).parent().find('.amount').val();
});
});
jQuery.post(newSession, {json: data.serializeArray()});
is there any better way for doing it? or how can i make it work?
help appreciated ;/
You need to initialize arrays and objects before using them. String indexes are only possible with objects. Try this:
var data = [];
jQuery(':checked').each(function(i)
{
data[i] = {};
data[i].productId = jQuery(this).parent().find('.productId').val();
data[i].attrGrps = [];
jQuery(this).parent().find('.attrGrp').each(function(j)
{
data[i].attrGrps[j] = {};
data[i].attrGrps[j].uid = jQuery(this).find('.active').attr('id');
data[i].attrGrps[j].amount = jQuery(this).parent().find('.amount').val();
});
});
Alternatively you could use jQuery().serialize, post everything in the form and sort it out on the server.
I am not totally familiar with javascript, jquery.
I am trying to do the following. Note a-f are names for the dropdown menus. Can someone help clarify? thanks
var a_params = $("#a").serializeArray();
var b_params = $("#b").serializeArray();
var c_params = $("#c").serializeArray();
var d_params = $("#d").serializeArray();
var e_params = $("#e").serializeArray();
var f_params = $("#f").serializeArray();
params.push({ name: 'menu_mode', value: '2-1' });
$.get("./scripts/model.cgi", a_params,b_params,c_params,d_params,e_params,f_params, function(data){
$("#grapharea").html(data);
$("#prog").html(" ");
});
More Comments: in the cgi script i am dumping the inputs to see if i am receiving the values from the a-f_params but this isn't the case. Any ideas why?
You have to create 1 array(or jquery-object in this case) from all object's, and serialize this array.
$('#a,#b,#c,#d,#e,#f').serializeArray();
But this is only needed, if you dont want to serialize e.g. all input-fields.
Otherwise you can use simply
$('#form').serializeArray();