config service: validate config values

This commit is contained in:
Adam
2019-08-08 13:00:22 -04:00
parent 4286c680f2
commit edfd52af23
2 changed files with 91 additions and 0 deletions

View File

@@ -26,6 +26,10 @@ package net.runelite.http.service.config;
import com.google.common.annotations.VisibleForTesting;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
@@ -52,6 +56,9 @@ import org.springframework.stereotype.Service;
@Service
public class ConfigService
{
private static final int MAX_DEPTH = 8;
private static final int MAX_VALUE_LENGTH = 262144;
private final Gson GSON = RuneLiteAPI.GSON;
private final UpdateOptions upsertUpdateOptions = new UpdateOptions().upsert(true);
@@ -139,6 +146,11 @@ public class ConfigService
return false;
}
if (!validateJson(value))
{
return false;
}
Object jsonValue = parseJsonString(value);
mongoCollection.updateOne(eq("_userId", userId),
set(split[0] + "." + split[1].replace('.', ':'), jsonValue),
@@ -205,4 +217,71 @@ public class ConfigService
}
return jsonValue;
}
@VisibleForTesting
static boolean validateJson(String value)
{
try
{
// I couldn't figure out a better way to do this than a second json parse
JsonElement jsonElement = RuneLiteAPI.GSON.fromJson(value, JsonElement.class);
return validateObject(jsonElement, 1);
}
catch (JsonSyntaxException ex)
{
// the client submits the string representation of objects which is not always valid json,
// eg. a value with a ':' in it. We just ignore it now. We can't json encode the values client
// side due to them already being strings, which prevents gson from being able to convert them
// to ints/floats/maps etc.
return value.length() < MAX_VALUE_LENGTH;
}
}
private static boolean validateObject(JsonElement jsonElement, int depth)
{
if (depth >= MAX_DEPTH)
{
return false;
}
if (jsonElement.isJsonObject())
{
JsonObject jsonObject = jsonElement.getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet())
{
JsonElement element = entry.getValue();
if (!validateObject(element, depth + 1))
{
return false;
}
}
}
else if (jsonElement.isJsonArray())
{
JsonArray jsonArray = jsonElement.getAsJsonArray();
for (int i = 0; i < jsonArray.size(); ++i)
{
JsonElement element = jsonArray.get(i);
if (!validateObject(element, depth + 1))
{
return false;
}
}
}
else if (jsonElement.isJsonPrimitive())
{
JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive();
String value = jsonPrimitive.getAsString();
if (value.length() >= MAX_VALUE_LENGTH)
{
return false;
}
}
return true;
}
}