Make sure all JSON/web text interactions are escaped and/or UTF-8

This commit is contained in:
Mike Primm 2011-06-02 00:20:25 -05:00
parent 3c793b5302
commit 0fdeee5177
5 changed files with 18 additions and 11 deletions

View File

@ -4,6 +4,9 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader; import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.Reader;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.Timer; import java.util.Timer;
@ -18,7 +21,7 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import static org.dynmap.JSONUtils.*; import static org.dynmap.JSONUtils.*;
import java.nio.charset.Charset;
public class JsonFileClientUpdateComponent extends ClientUpdateComponent { public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
protected TimerTask task; protected TimerTask task;
@ -27,6 +30,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
protected long currentTimestamp = 0; protected long currentTimestamp = 0;
protected long lastTimestamp = 0; protected long lastTimestamp = 0;
protected JSONParser parser = new JSONParser(); protected JSONParser parser = new JSONParser();
private Charset cs_utf8 = Charset.forName("UTF-8");
public JsonFileClientUpdateComponent(final DynmapPlugin plugin, final ConfigurationNode configuration) { public JsonFileClientUpdateComponent(final DynmapPlugin plugin, final ConfigurationNode configuration) {
super(plugin, configuration); super(plugin, configuration);
final boolean allowwebchat = configuration.getBoolean("allowwebchat", false); final boolean allowwebchat = configuration.getBoolean("allowwebchat", false);
@ -83,7 +87,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
try { try {
FileOutputStream fos = new FileOutputStream(outputTempFile); FileOutputStream fos = new FileOutputStream(outputTempFile);
fos.write(clientConfiguration.toJSONString().getBytes()); fos.write(clientConfiguration.toJSONString().getBytes("UTF-8"));
fos.close(); fos.close();
outputFile.delete(); outputFile.delete();
outputTempFile.renameTo(outputFile); outputTempFile.renameTo(outputFile);
@ -110,7 +114,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
outputTempFile = getStandaloneFile("dynmap_" + world.getName() + ".json.new"); outputTempFile = getStandaloneFile("dynmap_" + world.getName() + ".json.new");
try { try {
FileOutputStream fos = new FileOutputStream(outputTempFile); FileOutputStream fos = new FileOutputStream(outputTempFile);
fos.write(Json.stringifyJson(update).getBytes()); fos.write(Json.stringifyJson(update).getBytes("UTF-8"));
fos.close(); fos.close();
outputFile.delete(); outputFile.delete();
outputTempFile.renameTo(outputFile); outputTempFile.renameTo(outputFile);
@ -130,7 +134,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
if (webchatFile.exists() && lastTimestamp != 0) { if (webchatFile.exists() && lastTimestamp != 0) {
JSONArray jsonMsgs = null; JSONArray jsonMsgs = null;
try { try {
FileReader inputFileReader = new FileReader(webchatFile); Reader inputFileReader = new InputStreamReader(new FileInputStream(webchatFile), cs_utf8);
jsonMsgs = (JSONArray) parser.parse(inputFileReader); jsonMsgs = (JSONArray) parser.parse(inputFileReader);
inputFileReader.close(); inputFileReader.close();
} catch (IOException ex) { } catch (IOException ex) {

View File

@ -6,6 +6,8 @@ import java.lang.reflect.Modifier;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.json.simple.JSONObject;
public class Json { public class Json {
public static String stringifyJson(Object o) { public static String stringifyJson(Object o) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -19,7 +21,7 @@ public class Json {
} else if (o instanceof Boolean) { } else if (o instanceof Boolean) {
s.append(((Boolean) o) ? "true" : "false"); s.append(((Boolean) o) ? "true" : "false");
} else if (o instanceof String) { } else if (o instanceof String) {
s.append("\"" + ((String)o).replace("\"", "\\\"") + "\""); s.append("\"" + JSONObject.escape((String)o) + "\"");
} else if (o instanceof Integer || o instanceof Long || o instanceof Float || o instanceof Double) { } else if (o instanceof Integer || o instanceof Long || o instanceof Float || o instanceof Double) {
s.append(o.toString()); s.append(o.toString());
} else if (o instanceof Map<?, ?>) { } else if (o instanceof Map<?, ?>) {

View File

@ -33,12 +33,12 @@ public class ClientConfigurationHandler implements HttpHandler {
String s = configurationObject.toJSONString(); String s = configurationObject.toJSONString();
cachedConfiguration = s.getBytes(); cachedConfiguration = s.getBytes("UTF-8");
} }
String dateStr = new Date().toString(); String dateStr = new Date().toString();
response.fields.put("Date", dateStr); response.fields.put("Date", dateStr);
response.fields.put("Content-Type", "text/plain"); response.fields.put("Content-Type", "text/plain; charset=utf-8");
response.fields.put("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); response.fields.put("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
response.fields.put("Last-modified", dateStr); response.fields.put("Last-modified", dateStr);
response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length)); response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length));

View File

@ -67,11 +67,11 @@ public class ClientUpdateHandler implements HttpHandler {
s(u, "timestamp", current); s(u, "timestamp", current);
plugin.events.trigger("buildclientupdate", new ClientUpdateEvent(since, dynmapWorld, u)); plugin.events.trigger("buildclientupdate", new ClientUpdateEvent(since, dynmapWorld, u));
byte[] bytes = u.toJSONString().getBytes(); byte[] bytes = u.toJSONString().getBytes("UTF-8");
String dateStr = new Date().toString(); String dateStr = new Date().toString();
response.fields.put(HttpField.Date, dateStr); response.fields.put(HttpField.Date, dateStr);
response.fields.put(HttpField.ContentType, "text/plain"); response.fields.put(HttpField.ContentType, "text/plain; charset=utf-8");
response.fields.put(HttpField.Expires, "Thu, 01 Dec 1994 16:00:00 GMT"); response.fields.put(HttpField.Expires, "Thu, 01 Dec 1994 16:00:00 GMT");
response.fields.put(HttpField.LastModified, dateStr); response.fields.put(HttpField.LastModified, dateStr);
response.fields.put(HttpField.ContentLength, Integer.toString(bytes.length)); response.fields.put(HttpField.ContentLength, Integer.toString(bytes.length));

View File

@ -1,6 +1,7 @@
package org.dynmap.web.handlers; package org.dynmap.web.handlers;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -21,7 +22,7 @@ public class SendMessageHandler implements HttpHandler {
private static final JSONParser parser = new JSONParser(); private static final JSONParser parser = new JSONParser();
public Event<Message> onMessageReceived = new Event<SendMessageHandler.Message>(); public Event<Message> onMessageReceived = new Event<SendMessageHandler.Message>();
private Charset cs_utf8 = Charset.forName("UTF-8");
public int maximumMessageInterval = 1000; public int maximumMessageInterval = 1000;
public String spamMessage = "\"You may only chat once every %interval% seconds.\""; public String spamMessage = "\"You may only chat once every %interval% seconds.\"";
private HashMap<String, WebUser> disallowedUsers = new HashMap<String, WebUser>(); private HashMap<String, WebUser> disallowedUsers = new HashMap<String, WebUser>();
@ -36,7 +37,7 @@ public class SendMessageHandler implements HttpHandler {
return; return;
} }
InputStreamReader reader = new InputStreamReader(request.body); InputStreamReader reader = new InputStreamReader(request.body, cs_utf8);
JSONObject o = (JSONObject)parser.parse(reader); JSONObject o = (JSONObject)parser.parse(reader);
final Message message = new Message(); final Message message = new Message();