Should I use JSON econding, JavaScript encoding or both? - javascript

I’ve started to work with security of a website and my task is to prevent XSS attack. I’ve seen the OWASP rules to deal with it. However, I am not sure about which of these rules I should use on my specific case.
I have the following .jsp file:
<%
// Get Requests
InputData data = new InputData(request);
int idBcomp = data.getInt("bcomp");
Bcomp bcomp = new Bcomp();
BcompDao bcompDao = new BcompDaoImpl();
bcomp.setId(idBcomp);
JSONObject json = new JSONObject();
try {
for (Bcomp s : bcompDao.find(bcomp)) {
json.accumulate("id", s.getId());
json.accumulate("nome", s.getNome());
json.accumulate("nox", s.getNox());
}
} catch (SQLException e) {
json.accumulate("erro", e.getMessage());
} catch (Exception e) {
json.accumulate("erro", e.getMessage());
}
out.write(json.toString());
%>
I also have the .js file that receives and manipulates the JSON created by the file above. In this file I have the following code:
function import(idBcomp) {
$.ajax({
url: 'ajax/bcomp.jsp',
data: {bcomp: idBcomp}
}).done(function (r) {
var obj = $.parseJSON(r);
$("#nome").val(obj.nome);
$("#nox").val(obj.nox);
$("#id_bcomp").val(obj.id);
});
}
Therefore, my question is: Should I use javascript encode, JSON encode or both? And where should I do the encoding?
I am using OWASP XSS API for encodeForJavaScript and JSON encoding

JSON encoding. JSON indicates to the browser that the content is DATA ONLY and should not be executed. JavaScript encoding indicates a potentially executable bundle.

Related

How to get JSON file from server? (ASP.NET)

I have a simple web application that operates with a set of words using JS. In order to test the main code I just put a needed data in a variable in my script.
CONST WORDS = [
["Computer", "Ordinateur", "https://www.lifewire.com/thmb/nNDKywb8qvKzhxelVAR95sEHBj0=/768x0/filters:no_upscale():max_bytes(150000):strip_icc()/Acer-aspire-x3300-5804ec185f9b5805c2b6b9e6.jpg"],
["Function", "Fonction", "http://latex-cookbook.net/media/cookbook/examples/PNG/function-plot.png"],
["Server", "Serveur", "https://effortz.com/wp-content/uploads/dedicated-hosting-server.png"]
]
Now I need to build a database (already done) and get such data from the server. So, the question is how do I acquire JSON file from the server using JS? I know how to make GET requests, but what should I do on the server to make it response? (or may be there is an easier way to get this data in JS, considering that I already got it from DB and can easy display on the webpage).
Here is a backend code
namespace LFrench
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
List<Words> WordsSet = Words.GetWords("Business");//recieving from DB a set of words, that i need to use in JS
}
}
}
The thing you need to understand is the flow of your request. if you strictly want to do it in the Page_Loag event then I suppose you will have to make a method in your Javascript that will actually accept your data as parameter and then call the Javascript method from the C# CodeBehind Assuming that the data in the parameter is in JSON format. This method works but is not very efficient.
Other way is, in your JQuery side, you should make an ajax call to a WebMethod of yours in the CodeBehind that will actually send the response in JSON format. This is cleaner way of doing it.
Your JQuery should look like:
$(document).ready(function(){
$.ajax({
method: "GET", accept: "application/json; charset=utf-8;",
url: 'MyPage.aspx/GetDataFromDB', success: function(data){
console.log('Success Response in JSON: ' + data.d); // notice *data.d*, Calling from WebMethods returns the object encoded in the .d property of the object.
}, fail: function(err){
console.log(err);
}
});
});
And your CodeBehind should look like:
[WebMethod]
public static string GetDataFromDB()
{
var myData = YourDbCall(); // Some method to retrieve data from database
var body = new
{
Firstname = myData.Firstname,
Lastname = myData.Lastname,
Email = myData.Email,
// Any Other Information
};
var json = JsonConvert.SerializeObject(body);
return json;
}
EDIT
Here is how your Word Set will be sent back as JSON:
[WebMethod]
public static string GetDataFromDB()
{
List<Words> WordsSet = Words.GetWords("Business");
return JsonConvert.SerializeObject(WordsSet);
}
Make sure you have installed Newtonsoft.JSON from Nuget Package Manager Console. if not you can Open Package Manager Console and run this command:
PM> Install-Package Newtonsoft.Json
You need to make json return type method on serverside. Than call it from your get method and do your method on serverside and fill the List and return that list by converting JSON format.

Jquery, ajax and JSON: Parsing GET response fails, but only sometimes?

I am doing an ajax call with jquery which returns a json array and it works fine on some cases. On other cases however, the browser (ff and IE11) cannot parse the response. I'm including my script in my .jsp file like this:
<script type="text/javascript" charset="utf-8" src="../scripts/test.js"></script>
This is the structure of the json as shown in my servlet in the java console:
[{"key":"...","type":"...","content":"..."},
{"key":"...","type":"...","content":"..."},
...]
My request simply looks like this:
var url = document.location.origin + "/Servlet",
searchText = $("input[name=search]").val(),
types = getOptions();
$.ajaxSetup({
type: "GET",
url: url,
data: {"operation": "search", "searchText": searchText, "types": types, "resultNumber": 200},
datatype: "json",
success: function(result,status,xhr)
{
showResults(result);
},
cache: false
});
$.ajax();
My java method for creating the JSON array:
private JSONArray parseJSON (ArrayList<ResultObject> aResultList) throws JSONException
{
JSONArray resultJSONArray = new JSONArray();
for (ResultObject resultObject : aResultList)
{
JSONObject jsonObject = new JSONObject();
HashMap<String,String> fields = resultObject.getFields();
for (Map.Entry<String, String> entry : fields.entrySet())
{
jsonObject.put(entry.getKey(), entry.getValue());
}
resultJSONArray.put(jsonObject);
}
return resultJSONArray;
}
The servlet response looks like this:
protected void doGet(HttpServletRequest aRequest, HttpServletResponse aResponse)
throws ServletException, IOException
{
QueryObject queryObject = new QueryObject();
queryObject.setSearchText(aRequest.getParameter("searchText"));
String[] types = aRequest.getParameterValues("types[]");
queryObject.setTypes(types);
queryObject.setResultNumber(Integer.parseInt(aRequest.getParameter("resultNumber")));
JSONArray results = indexManager.doSearch(queryObject);
System.out.println(results.toString());
aResponse.getWriter().write(results.toString());
aResponse.setContentType("application/json");
// aResponse.setCharacterEncoding("UTF-8");
PrintWriter out = aResponse.getWriter();
out.flush();
}
I parse it with jquery like this:
function showResults (resultList)
{
$.each(resultList, function(i, item)
{
console.log(item.key);
});
}
Debugging shows me that sometimes the returned JSONarray is not parsed to JSON automatically but stays as a string, which is why $.each(..) fails. I could not determine why jquery has a problem parsing it, since it doesn't give me any error message. Parsing it manually with JSON.parse() however tells me that it does not seem to be valid. At first it did the request using $.get(...), which worked fine in FF but not in IE (caching problem). I thought it is a problem with german special characters (umlaut) but it is not the case. It rather seems that this always happens, when the jsonarray is of larger size (~ 50 objects and more). Unfortunately, i cannot post an example json here, since it contains sensible data.
I have wasted hours to solve this problem, so please someone has any idea about whats wrong here? Is there any tool that helps me validate my json and tell me why exactly it is invalid? or might the problem be of any else cause? Thanks.
I would comment but as i don't have 50 rep yet...
You can check if you JSON is valid with this tool https://jsonlint.com/ and about the JSON being too big I would not bet on it, there is no fixed limit on how large a JSON data block is or any of the fields (with the right amount of heap memory allocated to the jvm) . There are limits to how much JSON the JavaScript implementation of various browsers can handle (e.g. around 40MB in my experience).
Ok, i solved the problem: The problem was in my servlet. I had to set the content encoding properties for the response AT THE BEGINNING before i add the content to the writer. So it looks like this now:
protected void doGet(HttpServletRequest aRequest, HttpServletResponse aResponse)
throws ServletException, IOException
{
aResponse.setContentType("application/json");
aResponse.setCharacterEncoding("UTF-8");
QueryObject queryObject = new QueryObject();
queryObject.setSearchText(aRequest.getParameter("searchText"));
String[] types = aRequest.getParameterValues("types[]");
queryObject.setTypes(types);
queryObject.setResultNumber(Integer.parseInt(aRequest.getParameter("resultNumber")));
JSONArray results = indexManager.doSearch(queryObject);
aResponse.getWriter().write(results.toString());
PrintWriter out = aResponse.getWriter();
out.flush();
}

How can I send javascript as a string in a JSON parameter

I am building dynamic javascript in C# and sending it back to a single page application in a JSON request.
The problem is, the javascript/jquery in the JSON parameter breaks the JSON. How do I properly escape this?
Here is the code... it will combine many small segments of js from files into a string and inject it into a page.
Many thanks!
try
{ // Open the text file using a stream reader.
using (StreamReader sr = new StreamReader("dynamic.js"))
{
// Read the stream to a string, and write the string to the console.
dynamicJS = sr.ReadToEnd();
}
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
// user has been authenticated return data and JS to the front end
return $"{{ \"Email\": \"{userDetails.Email}\", \"DisplayName\": \"{userDetails.DisplayName}\", \"Services\": {safeServices.SerializeToJsonString()}, \"PageElements\": \"{pageURLs}\", \"DyanamicJS\": \"{dynamicJS}\" }}";

Opening a JSON file from javascript

I have a C# functoin in my MVC application that returns a JSON representation of a csv file. I am trying to catch that in javascript and open the file. Basically I want the browser do its thing and let the user decide if he want to open it, save it or cancel. I am unable to get that popup to ask me to open the file. Below are the functions
C# Function
[HttpPost]
public ActionResult ExportToCsv(string fileContents, string fileName)
{
fileContents = fileContents.Replace("-CARRIAGE-", "\r\n");
return Json(new { url = File(Encoding.UTF8.GetBytes(fileContents), "text/csv", fileName) }); ;
}
This is the javascript where I am making the ajax call to the function
$("#btnExport").click(function (event) {
event.preventDefault();
var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
$.ajax({
url: "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.csv",
type: 'Post',
success: function (result) {
window.open(result.url);
}
});
});
I know I am missing something. Can someone please help.
EDIT
After reading through all the potential answers and comments, this is what I am trying to achieve. So if my code is all horribly wrong please let me know.
I have a grid and I have an export to excel button. I have a method that converts the data i want into comma delimited text in javascript itself. I need to present this to the user as a downloadable csv file. For this I was creating the File object using the controller method. The previous incarnation was a Get method and I faced limitations due to querystring length restrictions. So I tried converting it to a POST method and it is not working.
This is the previous version of the code that works for smaller amounts of data
Javascript
$("#btnExport").click(function (event) {
event.preventDefault();
var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
window.location.href = "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.csv";
});
C# Function
[HttpGet]
public ActionResult ExportToCsv(string fileContents, string fileName)
{
fileContents = fileContents.Replace("-CARRIAGE-", "\r\n");
return File(Encoding.UTF8.GetBytes(fileContents), "text/csv", fileName);
}
Hope this now gives you all more context. Basically I needed to convert my GET method to a POST method and use it from Javascript.
If you use ajax, you're expected to handle the result in code. But you can't trigger a file download (directly) that way.
Instead, create a (hidden) form and post it to a (hidden) iframe (by giving the iframe a name and specifying that as the target of the form), making sure that the response specifies the header Content-Disposition: attachment. That will trigger the browser to offer to save the file. Optionally in the header you can suggest a filename for the file by adding ; filename="fname.ext" to the header value. E.g. Content-Disposition: attachment; filename="fname.ext".
The client-side looks something like this:
$("#btnExport").click(function (event) {
event.preventDefault();
var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
var frame = $('iframe[name="formreceiver"]');
if (!frame.length) {
frame = $('<iframe name="formreceiver"></iframe>').appendTo(document.body).css("display", "none");
}
var form = $("#senderform");
if (!form.length) {
form = $('<form id="senderform"></form>').appendTo(document.body);
}
form = form[0]; // Raw DOM element rather than jQuery wrapper
form.target = "formreceiver";
form.action = "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.csv";
form.method = "POST";
form.submit();
});
The server side is just a standard form response with the Content-Disposition header.
I've used this technique for years, with browsers from IE6 onward. My usual setup already has the iframe in the markup (rather than creating it as above), but other than that this is basically what I do.
Note that it's important you're doing this in response to a button click by the user. If you weren't, there would be popup-blocker issues.
You can't save binary files using ajax - it's restricted due to security reasons. If you'd like the user to save the file - return a binary stream from your controller as you post the data back in JSON format (ie if the user wants to save it).
I've done a similar thing here: How to properly create and download a dynamically generated binary *.xlsx file on .net MVC4?
Maybe save it as a json file instead and load in the current page's DOM. Although I though I am confused, don't you just have a JSON response containing a URL to your CSV file is which is just that a CSV file, not a JSON representation of CSV?
$("#btnExport").click(function (event) {
event.preventDefault();
var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
$.ajax({
url: "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.json",
type: 'Post',
success: function (result) {
var myDummyElement = $('<div>'); //dummy div so you can call load
myDummyElement .load('result.url #myJson');
}
});
});
<div id="myJson"></div>
[HttpPost]
public ActionResult ExportToCsv(string fileContents, string fileName)
{
//change fileName to be a .json extension
fileContents = fileContents.Replace("-CARRIAGE-", "\r\n");
return Json(new { url = File(Encoding.UTF8.GetBytes(fileContents), "text/csv", fileName) }); ;
}

Send JS object to JSP page [duplicate]

This question already has answers here:
Call Servlet and invoke Java code from JavaScript along with parameters
(3 answers)
Closed 6 years ago.
I have a JS object in a JavaScript file. I have to pass this object to a JSP page. The page picks up this object and processes it. How can I do it?
The same way you get any other data from a web browser to an HTTP server.
Encode it in an HTTP request by submitting a form / setting the window location / using XMLHttpRequest / etc.
There are a couple of issues you need to resolve first, are you doing this in an AJAX style of request? is this a form submission? is there going to be on-going interaction within the page-session between the client/server passing JSON objects back-and-forth?
Lets tackle the simple case of a form submission, once you get that you should be able to get the remaining cases going as they are just "extensions" of this base case. Say you have some form that will submit the data in some field:
<form name='my_form' id='my_ford_id'>
<input type='hidden' name='my_input_field' />
</form>
then at some point in time you have a piece of code that executes and you have your JSON object
function myFunction() {
var json_data = getJsonData();
document.forms['my_form']['my_input_field'].value = json_data;
document.forms['my_form'].submit();
}
You will then on the JSP side receive this data as a JSON string inside of a form field, at which point you need to process it, lets assume you have some kind of a JSON library available to you, the code might look something like this:
<%
String myInputField = request.getParameter("my_input_field");
if(myInputField != null) {
try {
JSONObject myObject = new JSONObject(myInputField);
}
catch(JSONException e) {
}
}
%>
If you need an "AJAX" style of interaction, you will be making a number of such requests in the page, but fundamentally it falls back to the original problem of submitting the data. Since you are using forms in this example, and JSP, you don't have to worry at any point about encoding, the browser/server will take care of things for you.
When you send json object the servlet receive it in the same way of receiving data sent by submitting the form, for example, if you send a variable "action" with value="getCountries"
var option = {
"action": "getCountries"
};
$.getJSON('YourServlet', option, function() {
//hadle the result returned by servlet
});
The defualt method is GET, in the servlet you handle the request as you handle a normal request
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
if (action != null) {
if (action.equals("getCountries")) {
List coutries = getAllICountries(request); //get the countries
String json = new Gson().toJson(coutries);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().write(json);
return;
}
}
}
Notice how we return the result from servlet to javascript, we return a json object.
"JSON" Site helps you to manage Json Objects in JSp/java.
You have to convert the string obtained from javascript to a json object.Then manage it easily.

Categories

Resources