지난 포스팅에서 lucy를 활용한 XSS처리를 등록 했었는데 알고보니 lucy 라이브러리는 form-data에 대해서만 적용되고 JSON에 대해서는 처리해주지 않고 있었다. 그래서 RequestBody로 넘어오는 JSON에 대한 필터를 등록하여 처리하는 방법을 작성 한다.
JSON데이터 XSS 처리 적용
pom.xml
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.9</version>
</dependency>
StringEscapeUtils 사용을 위해 dependency 추가
HTMLCharacterEscapes.java 생성
public class HTMLCharacterEscapes extends CharacterEscapes {
private final int[] asciiEscapes;
private final CharSequenceTranslator translator;
public HTMLCharacterEscapes() {
// 1. XSS 방지 처리할 특수 문자 지정
asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON();
asciiEscapes['<'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['>'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['&'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['\"'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['('] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes[')'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['#'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['\''] = CharacterEscapes.ESCAPE_CUSTOM;
//사용자 정의
Map<CharSequence, CharSequence> customMap = new HashMap<>();
customMap.put("(", "(");
// XSS 방지 처리 특수 문자 인코딩 값 지정
translator = new AggregateTranslator(
new LookupTranslator(EntityArrays.BASIC_ESCAPE), // <, >, &, " 는 여기에 포함됨
new LookupTranslator(EntityArrays.ISO8859_1_ESCAPE),
new LookupTranslator(EntityArrays.HTML40_EXTENDED_ESCAPE),
new LookupTranslator(CUSTOM_ESCAPE)
);
}
@Override
public int[] getEscapeCodesForAscii() {
return asciiEscapes;
}
@Override
public SerializableString getEscapeSequence(int ch) {
return new SerializedString(translator.translate(Character.toString((char) ch)));
// 참고 - 커스터마이징이 필요없다면 아래와 같이 Apache Commons Text에서 제공하는 메서드를 써도 된다.
// return new SerializedString(StringEscapeUtils.escapeHtml4(Character.toString((char) ch)));
}
}
MVC config
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(escapingConverter());
}
@Bean
public HttpMessageConverter escapingConverter() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.getFactory().setCharacterEscapes(new HTMLCharacterEscapes());
MappingJackson2HttpMessageConverter escapingConverter = new MappingJackson2HttpMessageConverter();
escapingConverter.setObjectMapper(objectMapper);
return escapingConverter;
}
}
참고사이트
https://github.com/Spring-Boot-Course/Spring-Boot-XSS-Protection
https://stackoverflow.com/questions/25403676/initbinder-with-requestbody-escaping-xss-in-spring-3-2-4
'Spring > Framework' 카테고리의 다른 글
[Spring] XSS(Cross-site scripting) 사이트 간 스크립팅 취약점 대응 (0) | 2023.04.17 |
---|---|
[Spring] Spring Framework와 Spring Boot의 차이점 (0) | 2023.04.11 |