- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在 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 :
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;
}
}
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": {
"<html>": "<script>(function(){alert('xss1')})();</script>"
},
"xss": "<script>(function(){alert('xss2')})();</script>"
}
关于Java 和 XSS : How to html escape a JSON string to protect against XSS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50857625/
这个问题在这里已经有了答案: How to make a property protected AND internal in C#? (8 个答案) 关闭 9 年前。 我需要声明一个既受又 内部保
我有以下代码: class Base{ protected val alpha ="Alpha"; protected def sayHello = "Hello"; } class
我正在尝试运行一个宏来创建一个工作正常的pdf。 Excel 文件获得签名后,Excel 文件将自动受到保护。 问题:我的工作表上有一个按钮,需要按下该按钮才能创建 pdf 文档网。然而,这是无法完成
子类需要能够使用种子随机数生成器。 使用的优点和缺点是什么 public abstract class AbstractClass { protected Random rnd; public
我们有两个类(class)(A 和 B)。 A类只能由继承它的类创建(A类)B 类可以由用户创建。 A 类,版本 1 有一个private 数据成员,并且有方法访问 A 类中的数据。 A 类,版本 2
当父类受到保护时,我对继承类的默认构造函数有疑问,在我看来,子类也会有一个默认构造函数受到保护,但事实并非如此。 除了在子类上强制默认构造函数外,还有其他方法可以强制保护默认构造函数吗? C++11
我有一个抽象类,我想在其 protected 构造函数中初始化一个只读字段。我希望这个只读字段在派生类中可用。 按照我将所有字段设为私有(private)并公开属性的习惯,我实现如下: abstrac
我在运行大数据时遇到错误。错误已由以下示例示例解释 加载数据 mdata <- as.matrix(read.table('https://gubox.box.com/shared/static
我在获取 时遇到问题非法访问错误 对于以下示例: 我在名为 arch 的 gradle 模块中声明了一个基类 abstract class BaseClass { protected abst
我相信通过 实现 JSF 应用程序的安全性+ + & 通过使用 是两种不同的方式!?他们是吗? 我尝试通过上述第一种方法(使用 + + )来实现安全性,但发现使用 protected 和不
有没有办法确定以下的二传手能见度差异: public Prop { get; protected set; } protected Prop { get; set; } 使用反射?还是那些与 C# 反
我读了一本关于 OOP 的书,并且关于“ protected ”访问修饰符的示例对我来说很奇怪。 例子总结 这个例子是为了测试“protected”保留字对变量的影响。 ClassA 有 2 个 pr
内部——在集会上公开,在其他地方私有(private)。 protected - 只有派生类可以访问父类成员。 Protected internal - protected OR internal -
我有一个类代表 Wicket 中带有“返回”、“前进”和“取消”按钮的基本页面。但并非所有页面都有所有按钮,例如。 G。第一页明显没有“返回”。 我的想法是定义一个通用的ActionHandler p
在了解到嵌套类是嵌套类的成员并因此可以完全访问嵌套类的成员这一事实后(至少对于 C++11,请参见 here),我在尝试创建嵌套类模板: #include using namespace std;
我刚刚使用了 Resharper,并一直在尝试将字段转换为属性。我希望这些属性受到保护,但 Resharper 不想给我这个选项。相反,只有一个 protected 内部选项。这让我思考。要么某处有一
这是 question 的扩展一个小时前问过。 当覆盖派生类中的虚方法时,我们不能修改访问修饰符。考虑 System.Web.UI 命名空间中的 Control 类 public class Cont
有人可以解释一下 C# 中 protected 和 protected internal 修饰符之间的区别吗?看起来他们的行为是相同的。 最佳答案 “protected internal”访问修饰符是
我想知道下面两行代码之间是否有区别: protected $var = null; protected $var; 我已经看到两者都被使用了,我想知道这是否只是一个偏好问题,(也就是 $var; 将变
我正在尝试使用mockito为“另存为”操作编写单元测试。该操作的一部分是制作并显示一个文件对话框,用户可以在其中输入要保存的文件。选择文件不是我可以自动化的操作,因此我想模拟 FileDialog
我是一名优秀的程序员,十分优秀!