gpt4 book ai didi

Java 和 XSS : How to html escape a JSON string to protect against XSS?

转载 作者:搜寻专家 更新时间:2023-10-31 19:59:35 27 4
gpt4 key购买 nike

在 Java 中,我们有一些代码接受复杂的 java 对象并将其序列化为 json。然后,它将 json 直接写入页面的标记,在脚本标记中,并将其分配给变量。

// Get object as JSON using Jackson
ObjectWriter jsonWriter = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = jsonWriter.writeValueAsString(complexObject);

// Write JSON out to page, and assign it to a javascript variable.
Writer out = environment.getOut();
out.write("var data = " + json);

复杂对象中可能包含最终用户内容,这可能使我们容易受到 XSS 攻击。

如何获取复杂 java 对象的 json 版本,每个 json 属性都经过 HTML 转义,以防止 XSS 注入(inject)?

我读过 OWASP XSS Guide到目前为止我想出的最好的是这个,HTML 转义整个 JSON 字符串,然后撤消引号,因此可以将其分配给 javascript 中的变量。我敢肯定有更好的方法可以做到这一点,但这似乎有效。有什么建议吗?

private String objectToHtmlEscapedJson(Object value) {
try {
String result = jsonWriter.writeValueAsString(value);
result = StringEscapeUtils.escapeHtml(result);
result = result.replace(""", "\"");
return result;
} catch (JsonProcessingException e) {
return "null";
}
}

最佳答案

一种可能的方法是遍历对象条目,并在节点由您选择的库构建后单独转义每个键和值。

根据我上面的评论,我使用 Jackson 实现了一个简单的递归解决方案(来自你的问题)和 GSON ,一个不同的库,其中对象更容易构造,代码更易读。使用的转义机制是 OWASP Java Encoder :

jackson

private static JsonNode clean(JsonNode node) {
if(node.isValueNode()) { // Base case - we have a Number, Boolean or String
if(JsonNodeType.STRING == node.getNodeType()) {
// Escape all String values
return JsonNodeFactory.instance.textNode(Encode.forHtml(node.asText()));
} else {
return node;
}
} else { // Recursive case - iterate over JSON object entries
ObjectNode clean = JsonNodeFactory.instance.objectNode();
for (Iterator<Map.Entry<String, JsonNode>> it = node.fields(); it.hasNext(); ) {
Map.Entry<String, JsonNode> entry = it.next();
// Encode the key right away and encode the value recursively
clean.set(Encode.forHtml(entry.getKey()), clean(entry.getValue()));
}
return clean;
}
}

GSON

private static JsonElement clean(JsonElement elem) {
if (elem.isJsonPrimitive()) { // Base case - we have a Number, Boolean or String
JsonPrimitive primitive = elem.getAsJsonPrimitive();
if(primitive.isString()) {
// Escape all String values
return new JsonPrimitive(Encode.forHtml(primitive.getAsString()));
} else {
return primitive;
}
} else if (elem.isJsonArray()) { // We have an array - GSON requires handling this separately
JsonArray cleanArray = new JsonArray();
for(JsonElement arrayElement: elem.getAsJsonArray()) {
cleanArray.add(clean(arrayElement));
}
return cleanArray;
} else { // Recursive case - iterate over JSON object entries
JsonObject obj = elem.getAsJsonObject();
JsonObject clean = new JsonObject();
for(Map.Entry<String, JsonElement> entry : obj.entrySet()) {
// Encode the key right away and encode the value recursively
clean.add(Encode.forHtml(entry.getKey()), clean(entry.getValue()));
}
return clean;
}
}

示例输入(两个库):

{
"nested": {
"<html>": "<script>(function(){alert('xss1')})();</script>"
},
"xss": "<script>(function(){alert('xss2')})();</script>"
}

示例输出(两个库):

{
"nested": {
"&lt;html&gt;": "&lt;script&gt;(function(){alert(&#39;xss1&#39;)})();&lt;/script&gt;"
},
"xss": "&lt;script&gt;(function(){alert(&#39;xss2&#39;)})();&lt;/script&gt;"
}

关于Java 和 XSS : How to html escape a JSON string to protect against XSS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50857625/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com