Security issue with JSON Stringify working on JS Array.

I was trying to pass some complex data using JQuery AJAX and JSON.Stringify to my PageMethod. I have this interesting find. In this example below, I have a textBox & 3 buttons which calls 3 respective server side static PageMethod functions. The first button does NOT use Stringify to pass data to server side. It just sends this parameter in the old way. The second button does use the stringify call — but on text or just any regular JS variable . The third button uses Stringify on a Javascript Array. Now if I inject some javascript in the textbox , something like (<script>alert(‘Hi’)</script>) and click the first button — the request does NOT even hit server & an error message pops-up. Very nice – because we want exactly this. Exact similar, with the second button click too. However, on third button hit, — the request really makes it to server & that’s scary. I ran my tests on IE 9 & Firefox 7.0.1 browsers. Let me know, if anybody else encountered this issue.

StringifyAndInjection

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="StringifyAndInjection.aspx.cs" Inherits="StringifyAndInjection" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(function () {
    $('#b1').click(function () {
        var tmp1 = $('[id$=TextBox1]')[0].value;
        $.ajax({
            type: "POST",
            url: "StringifyAndInjection.aspx/RegularJQueryAJAX",
            data: "{ 'title': '" + tmp1 + "' }",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                alert("Success" + data.d);
            },
            error: function (xhr, status, error) {
                alert("Error1" + xhr.responseText);
            }
        });
    });


    $('#b2').click(function () {
        var tmp1 = $('[id$=TextBox1]')[0].value;
        var a11 = {};
        a11.title = tmp1;
        var DTO = { 'a11': a11 };
        $.ajax({
            type: "POST",
            url: "StringifyAndInjection.aspx/StringifyJQueryAJAX",
            data: JSON.stringify(DTO),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                alert("Success" + data.d);
            },
            error: function (xhr, status, error) {
                alert("Error2" + xhr.responseText);
            }
        });
    });

    $('#b3').click(function () {
        var tmp1 = $('[id$=TextBox1]')[0].value;
        $.ajax({
            type: "POST",
            url: "StringifyAndInjection.aspx/StringifyJQueryAJAX2",
            data: JSON.stringify(tmp1),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                alert("Success" + data.d);
            },
            error: function (xhr, status, error) {
                alert("Error3" + xhr.responseText);
            }
        });
    });


});
</script>

</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><span>&nbsp;<b>Please enter some javascript script & try the below</b></span>
<br /><br /><br />
<input type="button" id="b1" value="RegularJQueryAJAX" />
&nbsp;&nbsp;<span style="color:Green;"><b>Complains Script Injection & the request does NOT hit server</b></span>
<br />
<input type="button" id="b3" value="Stringify-TEXT-JQueryAJAX" />
&nbsp;&nbsp;<span style="color:Green;"><b>Complains Script Injection & the request does NOT hit server</b></span>
<br />
<input type="button" id="b2" value="Stringify-ARRAY-JQueryAJAX" />
&nbsp;&nbsp;<span style="color:RED;"><b>Does NOT complain Script Injection & the request makes it to server</b></span>
</div>
</form>
</body>
</html>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;

public partial class StringifyAndInjection : System.Web.UI.Page
{
    public class a22
    {
        public string title { get; set; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    [WebMethod(EnableSession = true)]
    public static string RegularJQueryAJAX(string title)
    {
        return HttpUtility.HtmlEncode(title);
    }

    [WebMethod(EnableSession = true)]
    public static string StringifyJQueryAJAX2(string title)
    {
        return HttpUtility.HtmlEncode(title);
    }

    [WebMethod(EnableSession = true)]
    public static string StringifyJQueryAJAX(a22 a11)
    {
        return HttpUtility.HtmlEncode(a11.title);
    }
}

Thanks for reading.

Advertisements
This entry was posted in JQuery. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s