Als Fortsetzung des letzten Males möchte ich auf XSS-Maßnahmen eingehen. Es gibt verschiedene Arten von XSS, aber dieses Mal möchte ich mich auf die Probleme beim Einbetten von Java Script-Code in eine JSON-Zeichenfolge konzentrieren.
Beim letzten Mal hat die Serverseite ein Servlet erstellt, das JSON zurückgibt, wenn GET mit einer URL darauf zugreift. Dieses Mal wird es jedoch so verwendet, wie es ist. Versuchen Sie dann, den JavaScript-Code in die zurückgegebenen JSON-Daten einzubetten. Insbesondere wird der folgende JSON zurückgegeben.
{"id":1,"name":"kimisyo","datas":["Programmer","Data Scientist<script>alert('hello!')</script>"]}
Wenn es nicht ordnungsgemäß bereinigt wird, wird der JavaScript-Code im Teil `<script> alert ('hello!') </ Script>`
ausgeführt.
Greifen Sie zunächst als allgemeine Methode mit Ajax auf die URL des Servers zu, lesen Sie das Ergebnis als JSON und führen Sie JavaScirpt aus, um den Inhalt anzuzeigen. Die Quelle (JSP-Datei) lautet wie folgt.
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 des Kommunikationsziels
type:"GET", //Zu verwendende HTTP-Methode
// dataType:"json", //Antwortdatentyp
dataType:"text", //Antwortdatentyp(xml/html/script/json/jsonp/text)
timespan:1000 //Einstellung des Kommunikationszeitlimits(Millisekunde)
}).done(function(data,textStatus,jqXHR) {
var data2 = JSON.parse(data);
alert(data2.datas);
//Fehler wird ausgeführt, wenn die Kommunikation fehlschlägt
}).fail(function(jqXHR, textStatus, errorThrown ) {
alert("error");
//ist immer ein Erfolg/Wird unabhängig vom Fehler ausgeführt
}).always(function(){
alert("complete");
});
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>
Wenn Sie diese JSP-URL im Browser aufrufen, wird der Inhalt der JSON-Daten wie unten gezeigt angezeigt. Das in JSON eingebettete JavaScript wird unverändert als Daten gelesen, und es gibt kein Problem.
Versuchen Sie als Nächstes, die URL des Servlets zu ermitteln, das JSON direkt mit Edge zurückgibt. Dann wird das wunderschön eingebettete JavaScript vom Browser ausgeführt. Dies ist eine Operation, die ich nicht als Person sehen möchte, die an der serverseitigen Entwicklung beteiligt ist.
Das Problem ist, dass der Browser den von "<" und ">" umgebenen Teil als HTML-Tag erkennt, sodass Sonderzeichen wie "<", ">" in JSON Unicode-Escape-Sequenzen sind. Sie können es in konvertieren. Erstellen Sie zunächst die folgende Klasse. Fügen Sie der CustomCharacterEscapes-Methode die Zeichen hinzu, die Sie maskieren möchten.
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;
}
}
Nehmen Sie als Nächstes einige Änderungen am vorherigen Servlet vor.
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;
//Referenz 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 {
//Legen Sie einen Wert in einem Java-Objekt fest
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 {
//Vom Java-Objekt in JSON konvertieren
String testJson = mapper.writeValueAsString(jsonBean);
//JSON-Ausgabe
response.getWriter().write(testJson);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
Insbesondere wird `mapper.getFactory (). SetCharacterEscapes (neue CustomCharacterEscapes ());`
hinzugefügt.
Wenn Sie die obige Servlet-URL direkt vom Browser aus eingeben, wird sie wie folgt im Browser angezeigt. Es wurde in eine Unicode-Sequenz konvertiert und der eingebettete JavaScript-Code wird nicht ausgeführt.
{"id":1,"name":"kimisyo","datas":["Programmer","Data Scientist\u003Cscript\u003Ealert(\u0027hello!\u0027)\u003C\u002Fscript\u003E"]}
Wird es dann, selbst wenn es in eine Unicode-Sequenz konvertiert wird, korrekt als JSON-Daten auf der JavasScirpt-Seite interpretiert, die den JSON empfangen hat? Wenn Ajax mit JavaScript auf diesen JSON zugreift und ihn anzeigt, wird das Ergebnis des Lesens von "<" und ">" als JSON-Daten wie im Fall einer Nichtkonvertierung angezeigt, und es ist ersichtlich, dass sie korrekt interpretiert wurden.
Als nächstes möchte ich mich mit dem Problem befassen, JSON in HTML einzubetten und aus JavaScript zu verwenden.
Recommended Posts