Spring으로 웹 애플리케이션 개발시 보안을 위해 XSS 방지 처리를 해줘야 한다.
기존에 많이 사용되던 lucy-xss-servlet-filter는 form data 전송 방식에는 적용되지만 @RequestBody로 전달되는 JSON 요청은 처리해주지 않는다.
따라서 MessageConverter를 사용하는 방법으로 처리해줘야 한다.
우선 CharacterEscapes를 상속해 XSS 방지 처리할 특수문자를 지정해 준다. 그리고 StringEscapeUtils를 사용해 Escape 처리해준다(Commons Lang dependency 추가 필요).
public class HTMLCharacterEscapes extends CharacterEscapes {
private static final long serialVersionUID = 1L;
private final int[] asciiEscapes;
public HTMLCharacterEscapes() {
//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;
}
@Override
public int[] getEscapeCodesForAscii() {
return asciiEscapes;
}
@Override
public SerializableString getEscapeSequence(int ch) {
//Escape 처리
return new SerializedString(StringEscapeUtils.escapeHtml4(Character.toString((char) ch)));
}
}
ObjectMapper에 HTMLCharacterEscapes를 설정하고 MessageConverter에 등록해 XSS 방지 처리를 해준다. 이 때, 이 HttpMessageConverter를 Bean으로 등록해줘야 자동으로 메세지 컨버터 목록에 추가 된다.
ObjectMapper : JSON을 Java 객체로 역직렬화하거나 Java 객체를 JSON으로 직렬화할 때 사용하는 Jackson 라이브러리의 클래스이다. MappingJackson2HttpMessageConverter의 생성자에서 ObjectMapper를 생성해 가지고 있다.
@Configuration
@RequiredArgsConstructor
public class XssConfig {
//이미 기존에 등록된 ObjectMapper Bean이 있다면 JSON 요청/응답에서 사용하기 위해 의존성 주입을 받아 사용한다.
private final ObjectMapper objectMapper;
@Bean
public MappingJackson2HttpMessageConverter jsonEscapeConverter() {
ObjectMapper copy = objectMapper.copy();
copy.getFactory().setCharacterEscapes(new HTMLCharacterEscapes());
return new MappingJackson2HttpMessageConverter(copy);
}
}
참고) 만약 LocalDate 타입을 사용한다면 별도의 설정을 해줘야 한다. -> 참고용 링크
JSON에 대한 XSS 방지 처리가 필요하다면 CharacterEscapes를 상속하는 클래스 HtmlCharacterEscapes를 만들어 처리해야 할 특수문자를 지정하고 변환한 후,
ObjectMapper에 HtmlCharacterEscapes를 설정하고 MessageConverter에 등록해 Response가 클라이언트에 나가기 전에 처리 해주면 된다.
-끝😏-
https://jojoldu.tistory.com/470
https://homoefficio.github.io/2016/11/21/Spring%EC%97%90%EC%84%9C-JSON%EC%97%90-XSS-%EB%B0%A9%EC%A7%80-%EC%B2%98%EB%A6%AC-%ED%95%98%EA%B8%B0/