Neil Neil - 3 months ago 14
Ajax Question

Sanitize AJAX Response that updates Options in Select Box

I have

Bloggers
and
Blogs
. Each
blog
is associated to a
blogger
. Here is a picture of the Blog records:

blog records

Notice that the
title
attribute of Jennell's first
blog
has some javascript that could be triggered if not sanitized properly in certain situations.

Here is exactly one of those situations. I have two select Boxes:

two select boxes

For the first select box: the user picks a
Blogger
. When this happens:


  • an AJAX request gets sent to the server to grab all of the associated
    Blogs
    for that selected
    Blogger

  • the server grabs all the associated
    blogs
    to that
    blogger
    and sends them back to the requester

  • The response for the ajax request removes all options within the
    Blog
    select box

  • The response for the ajax request then adds in as options in that
    Blog
    select box all the
    blogs
    that were grabbed on the server.



The
Blogger
named Jennell has an associated
blog
with a
title
that contains a javascript hack. Thus: when the Jennell
Blogger
gets selected:

selecting blogger

That hack within her associated
Blog
will get executed:

javascript executed

Here is the actual code for the AJAX request:

$("body").on('change', '[data-action="blogger_sel"]', function() {
var blogger_sel = $(this).closest('[data-parent-for="blog_sel"]').find('[data-action="blog_sel"]');
$.ajax({
url: "/blogs",
type: "GET",
data: {blogger_id: $(this).val()},
success: function (data) {
blogger_sel.children().remove();
$.each(data, function (index, value) {
blogger_sel.append('<option value=' + value.id + '>' + value.title + '</option>');
});
}
})
});


The issue in the AJAX request is this part:

value.title


I need to sanitize that.

Question: Within the AJAX response: how can I sanitize
value.title
?




Answer



Below is a solution. Keep in mind that you should always sanitize data before it gets persisted into the database as well:

$("body").on('change', '[data-action="blogger_sel"]', function() {
var blogger_sel = $(this).closest('[data-parent-for="blog_sel"]').find('[data-action="blog_sel"]');
$.ajax({
url: "/blogs",
type: "GET",
data: {blogger_id: $(this).val()},
success: function (data) {
blogger_sel.children().remove();
$.each(data, function (index, value) {
var str = value.title;
var opt = $('<option></option>', {text: str, value: value.id});
blogger_sel.append(opt);
});
}
})
});

Answer

Set the text/values via attributes, not the html string.

var str = "<script>alert('x');<\/script>Test",
    opt = $("<option></option>", { "text" : str, value : "foo" });
$("select").append(opt);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select></select>