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.
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.
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.
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é.
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é.
Ensuite, je voudrais aborder le problème de l'intégration de JSON dans HTML et de son utilisation à partir de JavaScript.
Recommended Posts