我在我的方法中有一个@RequestBody注释参数,如下所示:
@RequestMapping(value = "/courses/{courseId}/{name}/comment", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
public @ResponseBody CommentContainer addComment(@PathVariable Long courseId,
@ActiveAccount Account currentUser,
@Valid @RequestBody AddCommentForm form,
BindingResult formBinding,
HttpServletRequest request) throws RequestValidationException {
.....
}
然后我在同一个控制器中有一个@InitBinder注释方法:
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(AddCommentForm.class, new StringEscapeEditor());
}
我的StringEscapeEditor没有运行.但我的initBinder方法是.所以它没有将我的表单映射到转义编辑器.这似乎是在阅读这个帖子后(@InitBinder不支持@RequestMapping):
spring mvc @InitBinder is not called when processing ajax request
我测试了映射@PathVariable字符串,然后我的编辑器工作.
这在我的应用程序中是一个大问题,因为我的大多数绑定都是使用@RequestBody完成的,如果我可以应用一些自定义绑定,它会很棒.
解决这个问题最常用的方法是什么?并且为了脚本攻击而逃避我的输入数据.
解决方法:
为了逃避XSS,我建议在输出数据时进行转义,因为正确的转义取决于输出文档.
如果@ResponseBody生成的JSON响应由客户端直接使用,并且没有机会让XSS转义内容,则可以自定义JacksonMessageConverter以对字符串执行XSS转义.
可以像这样自定义JacksonMessageConverter:
1)首先我们创建ObjectMapper工厂,它将创建我们的自定义对象映射器:
public class HtmlEscapingObjectMapperFactory implements factorybean<ObjectMapper> {
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['<'] = CharacterEscapes.ESCAPE_CUSTOM;
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的灵感来自这个问题:HTML escape with Spring MVC and Jackson Mapper)
2)然后我们注册使用我们的自定义对象映射器的消息转换器(xml配置中的示例):
<bean id="htmlEscapingObjectMapper" class="com.example.HtmlEscapingObjectMapperFactory" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" p:objectMapper-ref="htmlEscapingObjectMapper" />
</mvc:message-converters>
</mvc:annotation-driven>
现在,由@ResponseBody创建的所有JSON消息都应该按照HTMLCharacterEscapes中的指定转义字符串.
该问题的替代解决方案:
>在反序列化对象后,XSS将在控制器主体中转义所需的内容
>在输出内容之前,也许XSS在客户端的javascript中转义
除了执行输出转义之外,还可以使用一些输入验证(使用标准的Spring验证方法)来阻止您不希望输入系统/数据库的一些内容.
编辑:JavaConfig
我没有试过这个,但是在Java配置中它应该像这样工作(你不需要上面的Factory Bean,因为你可以在这种情况下在config中设置所有内容):
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> 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节)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。