我们使用 Spring 及其内置的 MappingJacksonHttpMessageConverter 生成大量 JSON 对象。一切都很棒。
但现在我想html转义我的(任何类型)对象的字符串值,以防止XSS。
那么,我该如何解决这个问题呢?我首先想到我可以编写一个自定义对象映射器并将其放入 MappkingJacksonHttpMessageConverter 中。但是, writeValue 接受一个对象,而我不希望这样,我想要它的 fields 进行迭代。我打赌杰克逊转换器也需要这样做,而不是我自己这样做。所以我想影响那部分。
现在我最终得到了一个 SerializerProvider 接口。标准实现 (StdSerializerProvider) 由 ObjectMapper 调用。所以我想在某个地方覆盖/影响负责设置值的方法。
这可能吗?据我所知,很难扩展。我无法重写 StdSerializerProvider 来重写 ObjectMapper 使用的方法。也许我需要覆盖另一个?
或者,也许这是完全错误的,我需要从完全不同的角度来处理它?
有什么想法吗?
哦顺便说一句,我自己实现 SerializerProvider 并创建委托给 StdSerializerProvider 的组合可能是可能的,但我宁愿不这样做。 (我自己实例化 StdSerializerProvider 时已经遇到问题)。
任何想法表示赞赏!
有多种方法,具体取决于您如何识别您想要逃避的事物。一些想法:
给出了这个答案,而问题是关于验证字符串不包含XSS并且不转义。如果您想转义字符串,这个答案对您没有帮助。
使用 JSR 303 Bean Validation 验证创建的对象(命令对象)怎么样?
例如,对“命令对象”的 String 属性使用 not @NotHtml(注释和验证)。
(当然你必须自己实现@NotHtml(@NotJavaScript或@NotXSS)注释和验证器。)
您可以为此创建自定义
CharacterEscapes
实现:
// Custom CharacterEscapes implementation to treat HTML characters like GSON does by default
// (inspired by https://www.cowtowncoder.com/blog/archives/2012/08/entry_476.html)
private final static class HtmlCharacterEscapes extends CharacterEscapes {
private final int[] asciiEscapes;
public HtmlCharacterEscapes() {
// start with set of characters known to require escaping (double-quote, backslash etc)
int[] esc = CharacterEscapes.standardAsciiEscapesForJSON();
// and force escaping of a few others:
esc['<'] = CharacterEscapes.ESCAPE_STANDARD;
esc['>'] = CharacterEscapes.ESCAPE_STANDARD;
esc['&'] = CharacterEscapes.ESCAPE_STANDARD;
esc['='] = CharacterEscapes.ESCAPE_STANDARD;
esc['\''] = CharacterEscapes.ESCAPE_STANDARD;
asciiEscapes = esc;
}
// this method gets called for character codes 0 - 127
@Override public int[] getEscapeCodesForAscii() {
return asciiEscapes;
}
// and this for others; we don't need anything special here
@Override public SerializableString getEscapeSequence(int ch) {
// no further escaping (beyond ASCII chars) needed:
return null;
}
}
我实际上在 StaxMan 的博客上找到了这个,所以我想知道为什么他们没有在答案中添加这个选项。
然后你有几个选项来注册它(
MAPPER_INSTANCE
将是静态/缓存的JsonMapper
):
创建一个 HTML 转义 JSON writer 实例:
ObjectWriter writer = MAPPER_INSTANCE.writer(new HtmlCharacterEscapes());.writer(new HtmlCharacterEscapes());
在映射器上全局注册它:
MAPPER_INSTANCE.getFactory().setCharacterEscapes(new HtmlCharacterEscapes());
在Spring Boot中全局注册:
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
return new Jackson2ObjectMapperBuilder().factory(new JsonFactory().setCharacterEscapes(new HtmlCharacterEscapes()));
}