小编典典
为了逃避XSS,我建议在输出数据时进行转义,因为正确的转义取决于输出文档。
如果@ResponseBody客户端直接使用所产生的JSON响应,并且没有机会让XSS转义内容,那么可以自定义JacksonMessageConverter以对字符串执行XSS转义。
可以像这样自定义JacksonMessageConverter:
1)首先,我们创建ObjectMapper工厂,该工厂将创建我们的自定义对象映射器:
public class HtmlEscapingObjectMapperFactory implements FactoryBean {
private final ObjectMapper objectMapper;
public HtmlEscapingObjectMapperFactory() {
objectMapper = new ObjectMapper();
objectMapper.getJsonFactory().setCharacterEscapes(new HTMLCharacterEscapes());
}
@Override
public ObjectMapper getObject() throws Exception {
return objectMapper;
}
@Override
public Class> getObjectType() {
return ObjectMapper.class;
}
@Override
public boolean isSingleton() {
return true;
}
public static class HTMLCharacterEscapes extends CharacterEscapes {
private final int[] asciiEscapes;
public HTMLCharacterEscapes() {
// start with set of characters known to require escaping (double-quote, backslash etc)
asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON();
// and force escaping of a few others:
asciiEscapes['
asciiEscapes['>'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['&'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['"'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['\''] = CharacterEscapes.ESCAPE_CUSTOM;
}
@Override
public int[] getEscapeCodesForAscii() {
return asciiEscapes;
}
// and this for others; we don't need anything special here
@Override
public SerializableString getEscapeSequence(int ch) {
return new SerializedString(StringEscapeUtils.escapeHtml4(Character.toString((char) ch)));
}
}
}
(HtmlCharacterEscapes的灵感来自于这个问题:Spring MVC和Jackson
Mapper的HTML转义)
2)然后,我们注册使用自定义对象映射器的消息转换器(例如xml config中的示例):
现在,由创建的所有JSON消息@ResponseBody都应具有HTMLCharacterEscapes中指定的转义字符串。
该问题的替代解决方案:
对象反序列化后,XSS可以在控制器主体中逃脱所需的操作
也许XSS在输出内容之前先在客户端的javascript中转义
除了进行输出转义之外,还可以进行一些输入验证(使用标准的Spring验证方法)来阻止一些您不想输入到系统/数据库中的内容,这可能是有用的。
编辑:JavaConfig
我还没有尝试过,但是在Java配置中它应该像这样工作(您不需要上面的Factory Bean,因为在这种情况下您可以在config中设置所有内容):
@Override
public void configureMessageConverters(List> converters) {
super.configureMessageConverters(converters);
converters.add(buildHtmlEscapingJsonConverter());
}
private MappingJacksonHttpMessageConverter buildHtmlEscapingJsonConverter() {
MappingJacksonHttpMessageConverter htmlEscapingConverter = new MappingJacksonHttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.getJsonFactory().setCharacterEscapes(new HTMLCharacterEscapes());
htmlEscapingConverter.setObjectMapper(objectMapper);
return htmlEscapingConverter;
}
请注意,现在通常配置的所有其他非json默认消息转换器(例如XML转换器等)都将丢失,并且如果需要它们,则需要手动添加它们(您可以看到默认情况下处于活动状态)在第2.2节中:http : //www.baeldung.com/spring-httpmessageconverter-
rest)
2020-07-26