JSON with Java and Jackson Part 2 XSS measures

Introduction

As a continuation of the last time, I would like to touch on XSS countermeasures. There are various types of XSS, but this time I would like to focus on the problems when embedding Java Script code in a JSON string.

environment

Problematic situation

Last time, the server side created a Servlet that returns JSON when accessed by GET with a URL, but this time it will be used as it is. Then, try embedding the JavaScript code in the returned JSON data. Specifically, the following JSON is returned.

{"id":1,"name":"kimisyo","datas":["Programmer","Data Scientist<script>alert('hello!')</script>"]}

If it is not sanitized properly, the JavaScript code in the `<script> alert ('hello!') </ Script>` part will be executed.

First, as a general method, access the URL of the server with Ajax, read the result as JSON, and execute JavaScirpt to display the contents. The source (jsp file) is as follows.

clientTest.jsp


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery Hello World</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>

$.ajax({
	url:"http://localhost:8080/servletTest/helloworld", //URL of the communication destination
	type:"GET",		//HTTP method to use
	// dataType:"json", //Response data type
	dataType:"text", //Response data type(xml/html/script/json/jsonp/text)
	timespan:1000 		//Communication timeout setting(millisecond)
	}).done(function(data,textStatus,jqXHR) {
		var data2 = JSON.parse(data);
		alert(data2.datas);
	//fail is executed when communication fails
	}).fail(function(jqXHR, textStatus, errorThrown ) {
		alert("error");
	//always is a success/Executed regardless of failure
	}).always(function(){
		alert("complete");
});


</script>
</head>
<body>
	<div id="test"></div>
</body>
</html>

When you hit the URL of this jsp from the browser, the contents of the JSON data will be displayed as shown below. The JavaScript embedded in JSON is read as data as it is, and there is no problem.

image.png

Next, try hitting the URL of the Servlet that returns JSON directly in Edge. Then, the beautifully embedded JavaScript is executed by the browser. This is an operation that I don't want to see as a person involved in server-side development.

image.png

Workaround

The problem is that the browser recognizes the part surrounded by "<" and ">" as an html tag, so special characters such as "<", ">" in JSON are Unicode escape sequences. You can convert it to. First, create the following class. Add the characters you want to escape to the CustomCharacterEscapes method.

CustomCharacterEscapes.java



package servletTest;

import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.CharacterEscapes;

public class CustomCharacterEscapes extends CharacterEscapes {

	private final int[] asciiEscapes;

    public CustomCharacterEscapes()
    {
        int[] esc = CharacterEscapes.standardAsciiEscapesForJSON();
        esc['"']  = CharacterEscapes.ESCAPE_STANDARD;
        esc['\''] = CharacterEscapes.ESCAPE_STANDARD;
        esc['/']  = CharacterEscapes.ESCAPE_STANDARD;
        esc['\n'] = CharacterEscapes.ESCAPE_STANDARD;
        esc['>'] = CharacterEscapes.ESCAPE_STANDARD;
        esc['<'] = CharacterEscapes.ESCAPE_STANDARD;
        asciiEscapes = esc;
    }

    @Override
    public int[] getEscapeCodesForAscii() {
        return asciiEscapes;
    }

    // no further escaping (beyond ASCII chars) needed:
    @Override
    public SerializableString getEscapeSequence(int ch) {
        return null;
    }
}

Next, I will make some corrections in the previous Servlet.

ServletTest.java


package servletTest;

import java.io.IOException;
import java.util.List;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;


//Reference https://itsakura.com/java-jackson

@WebServlet("/helloworld")
public class ServletTest extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    	//Set a value in a Java object
    	JsonBean jsonBean = new JsonBean();
    	jsonBean.setId(1);
    	jsonBean.setName("kimisyo");
    	List<String> datas = new ArrayList<>();
    	datas.add("Programmer");
    	datas.add("Data Scientist<script>alert('hello!')</script>");
    	jsonBean.setDatas(datas);

    	ObjectMapper mapper = new ObjectMapper();
    	mapper.getFactory().setCharacterEscapes(new CustomCharacterEscapes());

    	try {
    		//Convert from Java object to JSON
    		String testJson = mapper.writeValueAsString(jsonBean);

    		//JSON output
    		response.getWriter().write(testJson);
    	} catch (JsonProcessingException e) {
    		e.printStackTrace();
    	}
    }
}

Specifically, `mapper.getFactory (). SetCharacterEscapes (new CustomCharacterEscapes ());` is added.

Let's experiment

If you hit the URL of the above Servlet directly from the browser, it will be displayed on the browser as follows. It has been converted to a Unicode sequence and the embedded JavaScript code is not executed.

{"id":1,"name":"kimisyo","datas":["Programmer","Data Scientist\u003Cscript\u003Ealert(\u0027hello!\u0027)\u003C\u002Fscript\u003E"]}

Then, even if it is converted to a Unicode sequence, will it be correctly interpreted as JSON data on the JavasScirpt side that received the JSON? When this JSON is accessed by Ajax with JavaScript and displayed, the result of reading "<" and ">" as JSON data is displayed as in the case of not converting, and it can be seen that it was interpreted correctly.

in conclusion

Next, I would like to deal with the problem of embedding JSON in HTML and using it from JavaScript.

reference

-[[Java] Escape multibyte characters in Jackson](https://atuweb.net/201608_java-jackson-escape-multibytechars/#%E3%83%9E%E3%83%AB%E3%83%81] % E3% 83% 90% E3% 82% A4% E3% 83% 88% E6% 96% 87% E5% AD% 97% E3% 82% 92% E3% 82% A8% E3% 82% B9% E3 % 82% B1% E3% 83% BC% E3% 83% 97)

Recommended Posts

JSON with Java and Jackson Part 2 XSS measures
JSON in Java and Jackson Part 1 Return JSON from the server
JSON in Java and Jackson Part ③ Embed JSON in HTML and use it from JavaScript
Convert JSON and YAML in Java (using Jackson and SnakeYAML)
Convert Java enum enums and JSON to and from Jackson
[Java] Convert JSON to Java and Java to JSON-How to use GSON and Jackson-
Java and Iterator Part 1 External Iterator
Apache Hadoop and Java 9 (Part 1)
Solving with Ruby, Perl and Java AtCoder ABC 129 C (Part 1)
Java to learn with ramen [Part 1]
Use java with MSYS and Cygwin
Distributed tracing with OpenCensus and Java
Install Java and Tomcat with Ansible
Use JDBC with Java and Scala.
Output PDF and TIFF with Java 8
Server processing with Java (Introduction part.1)
Encrypt with Java and decrypt with C #
Shape and serialize nicely with Jackson
[Java] Get Json from URL and handle it with standard API (javax.script)
Sample code to serialize and deserialize Java Enum enums and JSON in Jackson
Link Java and C ++ code with SWIG
Let's try WebSocket with Java and javascript!
[Java] Reading and writing files with OpenCSV
Getting Started with Java Starting from 0 Part 1
AWS Lambda with Java starting now Part 1
Parse and objectize JSON using the @JsonProperty annotation of the Java library Jackson
Solving with Ruby, Perl and Java AtCoder ABC 129 C (Part 2) Dynamic programming
[Java] Output the result of ffprobe -show_streams in JSON and map it to an object with Jackson
Working with huge JSON in Java Lambda
Convert JSON to TSV and TSV to JSON with Ruby
Build and test Java + Gradle applications with Wercker
[Java] The confusing part of String and StringBuilder
Try to link Ruby and Java with Dapr
Prepare a scraping environment with Docker and Java
KMS) Envelope encryption with openssl and java decryption
Encrypt / decrypt with AES256 in PHP and Java
[Java] Convert and import file values with OpenCSV
[Review] Reading and writing files with java (JDK6)
java practice part 1
Diffed with JSON
Java and JavaScript
XXE and Java
[Java] Cut out a part of the character string with Matcher and regular expression
[Java] Align characters even with mixed half-width and full-width characters
Use fast Mapping library MapStruct with Lombok and Java 11
[Java] Find prime numbers with an Eratosthenes sieve (Part 2)
Solving with Ruby and Java AtCoder ABC129 D 2D array
Summary of ToString behavior with Java and Groovy annotations
Compile with Java 6 and test with Java 11 while running Maven on Java 8
Solving with Ruby, Perl and Java AtCoder ABC 128 C
[Java] Refer to and set private variables with reflection
I want to transition screens with kotlin and java!
Prepare the environment for java11 and javaFx with Ubuntu 18.4
Mutual conversion between Java objects and JSON using Moshi
Face recognition app made with Amazon Rekognition and Java
[Java] Development with multiple files using package and import
Replace only part of the URL host with java
Serverless Java EE starting with Quarkus and Cloud Run
Access Web API on Android with Get and process Json (Java for the time being)
Easy to make LINE BOT with Java Servlet Part 2: I tried image messages and templates