JSON avec Java et Jackson Part 2 XSS mesures

introduction

Dans le prolongement de la dernière fois, je voudrais aborder les mesures XSS. Il existe différents types de XSS, mais cette fois, je voudrais me concentrer sur les problèmes lors de l'incorporation de code Java Script dans une chaîne de caractères JSON.

environnement

Situation problématique

La dernière fois, le côté serveur a créé un servlet qui renvoie JSON lors de l'accès par GET avec une URL, mais cette fois, il sera utilisé tel quel. Ensuite, essayez d'incorporer le code JavaScript dans les données JSON renvoyées. Plus précisément, le JSON suivant est renvoyé.

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

S'il n'est pas nettoyé correctement, le code JavaScript de la partie <script> alert ('hello!') </ Script> sera exécuté.

Tout d'abord, en tant que méthode générale, accédez à l'URL du serveur avec Ajax, lisez le résultat au format JSON et exécutez JavaScirpt pour afficher le contenu. La source (fichier jsp) est la suivante.

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 de destination de la communication
	type:"GET",		//Méthode HTTP à utiliser
	// dataType:"json", //Type de données de réponse
	dataType:"text", //Type de données de réponse(xml/html/script/json/jsonp/text)
	timespan:1000 		//Réglage du délai de communication(milliseconde)
	}).done(function(data,textStatus,jqXHR) {
		var data2 = JSON.parse(data);
		alert(data2.datas);
	//échec est exécuté lorsque la communication échoue
	}).fail(function(jqXHR, textStatus, errorThrown ) {
		alert("error");
	//est toujours un succès/Exécuté indépendamment de l'échec
	}).always(function(){
		alert("complete");
});


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

Lorsque vous cliquez sur cette URL jsp à partir du navigateur, le contenu des données JSON sera affiché comme indiqué ci-dessous. Le JavaScript intégré dans JSON est lu en tant que données tel quel, et il n'y a aucun problème.

image.png

Ensuite, essayez de frapper l'URL du servlet qui renvoie JSON directement avec Edge. Ensuite, le JavaScript magnifiquement intégré sera exécuté par le navigateur. C'est une opération que je ne veux pas voir comme une personne impliquée dans le développement côté serveur.

image.png

solution de contournement

Le problème est que le navigateur reconnaît la partie entourée par "<" et ">" comme une balise html, donc les caractères spéciaux tels que "<", ">" dans JSON sont des séquences d'échappement Unicode. Vous pouvez le convertir en. Commencez par créer la classe suivante. Ajoutez les caractères que vous souhaitez échapper à la méthode CustomCharacterEscapes.

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;
    }
}

Ensuite, apportez quelques modifications dans le servlet précédent.

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;


//Référence 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 {

    	//Définir la valeur dans l'objet Java
    	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 {
    		//Convertir d'un objet Java en JSON
    		String testJson = mapper.writeValueAsString(jsonBean);

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

Plus précisément, mapper.getFactory (). SetCharacterEscapes (new CustomCharacterEscapes ()); `` est ajouté.

Expérimentons

Si vous cliquez sur l'URL du servlet ci-dessus directement à partir du navigateur, elle sera affichée sur le navigateur comme suit. Il a été converti en une séquence Unicode et le code JavaScript intégré n'est pas exécuté.

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

Ensuite, même s'il est converti en une séquence Unicode, sera-t-il correctement interprété comme des données JSON du côté JavasScirpt qui a reçu le JSON? Lorsque ce JSON est accédé par Ajax avec JavaScript et affiché, le résultat de la lecture de "<" et ">" en tant que données JSON est affiché comme dans le cas d'une non conversion, et on peut voir qu'il a été correctement interprété.

en conclusion

Ensuite, je voudrais aborder le problème de l'intégration de JSON dans HTML et de son utilisation à partir de JavaScript.

référence

Recommended Posts

JSON avec Java et Jackson Part 2 XSS mesures
JSON en Java et Jackson Partie 1 Renvoyer JSON à partir du serveur
JSON en Java et Jackson Part ③ Incorporer JSON dans HTML et l'utiliser à partir de JavaScript
Convertir JSON et YAML en Java (en utilisant Jackson et SnakeYAML)
Convertir l'énumération Java et JSON vers et depuis Jackson
[Java] Convertir JSON en Java et Java en JSON-Comment utiliser GSON et Jackson-
Java et Iterator Part 1 External Iterator Edition
Apache Hadoop et Java 9 (partie 1)
Résolution avec Ruby, Perl et Java AtCoder ABC 129 C (Partie 1)
Java pour apprendre avec les ramen [Partie 1]
Utiliser java avec MSYS et Cygwin
Traçage distribué avec OpenCensus et Java
Installez Java et Tomcat avec Ansible
Utilisez JDBC avec Java et Scala.
Sortie PDF et TIFF avec Java 8
Traitement serveur avec Java (Introduction partie 1)
Crypter avec Java et décrypter avec C #
Formez et sérialisez bien avec Jackson
[Java] Obtenir et gérer Json à partir d'une URL avec une API standard (javax.script)
Exemple de code pour la sérialisation et la désérialisation des énumérations Java Enum et JSON dans Jackson
Lier le code Java et C ++ avec SWIG
Essayons WebSocket avec Java et javascript!
[Java] Lecture et écriture de fichiers avec OpenCSV
Introduction à Java à partir de 0 Partie 1
AWS Lambda (Lambda) Partie 1 avec Java pour démarrer maintenant
Analyser et objectiver JSON à l'aide de l'annotation @JsonProperty de la bibliothèque Java Jackson
Résolution avec Ruby, Perl et Java AtCoder ABC 129 C (Partie 2) Méthode de planification dynamique
[Java] Affiche le résultat de ffprobe -show_streams dans JSON et mappe-le à un objet dans Jackson
Gérez d'énormes JSON avec Java Lambda
Conversion de JSON en TSV et TSV en JSON avec Ruby
Créez et testez des applications Java + Gradle avec Wercker
[Java] La partie déroutante de String et StringBuilder
Essayez d'intégrer Ruby et Java avec Dapr
Préparer un environnement de scraping avec Docker et Java
KMS) Chiffrement d'enveloppe avec décryptage openssl et java
Crypter / décrypter avec AES256 en PHP et Java
[Java] Convertir et importer des valeurs de fichier avec OpenCSV
[Review] Lecture et écriture de fichiers avec java (JDK6)
java pratique partie 1
Différé avec JSON
Java et JavaScript
XXE et Java
[Java] Découpez une partie de la chaîne de caractères avec Matcher et des expressions régulières
[Java] Aligne les caractères même avec des caractères mixtes demi-largeur et pleine largeur
Utilisez Fast Mapping Livery MapStruct avec Lombok et Java 11
[Java] Trouvez le nombre premier avec le tamis Eratostenes (Partie 2)
Tableau 2D AtCoder ABC129 D résolu en Ruby et Java
Résumé du comportement de ToString avec les annotations Java et Groovy
Exécutez Maven sur Java 8 lors de la compilation sur Java 6 et des tests sur Java 11
Résolution avec Ruby, Perl et Java AtCoder ABC 128 C
[Java] Se référer et définir des variables privées avec réflexion
Je veux faire des transitions d'écran avec kotlin et java!
Préparer l'environnement pour java11 et javaFx avec Ubuntu 18.4
Conversion entre objets Java et JSON à l'aide de Moshi
Application de reconnaissance faciale conçue avec Amazon Rekognition et Java
[Java] Développement avec plusieurs fichiers en utilisant package et import
Remplacez seulement une partie de l'hôte URL par java
Java EE sans serveur à partir de Quarkus et Cloud Run
Accédez à l'API Web avec Get sur Android et traitez Json (Java pour le moment)
Facile à créer LINE BOT avec Java Servlet Partie 2: J'ai essayé des messages image et des modèles