[SpringBoot] JSON API에서 XSS Filter 적용하기

손성우·2022년 8월 15일

스프링부트

목록 보기
3/4

XSS 방지에 많이 사용되는 네이버가 개발한 LUCY 필터의 단점은 from data전송 방식만 적용이되고 @RequestBody로 전달되는 JSON 요청은 적용되지 않아서 따로 처리를 해주어야 한다.
자세한 내용은 맨 밑에 참고주소에서 확인하시기 바랍니다.

실행 환경

  • java 11
  • Spring Boot 2.7.2
  • gradle

기본 LUCY 세팅

친절하게 설명 다 나와있다.
Gradle인경우

//xss예방 - 네이버 filter
    implementation 'com.navercorp.lucy:lucy-xss-servlet:2.0.0'
    implementation 'com.navercorp.lucy:lucy-xss:1.6.3'
    //StringEscapeUtils 를 사용하기 위해 commons-text 의존성 추가
    implementation 'org.apache.commons:commons-text:1.8'

LUCY 공식문서 : https://github.com/naver/lucy-xss-servlet-filter

JSON API XSS 해결 방법

  1. HtmlCharacterEscapes
package hanghae8mini.booglogbackend.secure;

import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.CharacterEscapes;
import com.fasterxml.jackson.core.io.SerializedString;
import org.apache.commons.text.StringEscapeUtils;

public class HTMLCharacterEscapes extends CharacterEscapes {

    private final int[] asciiEscapes;

    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;

    }

    @Override
    public int[] getEscapeCodesForAscii() {
        return asciiEscapes;
    }

    @Override
    public SerializableString getEscapeSequence(int ch) {
        return new SerializedString(StringEscapeUtils.escapeHtml4(Character.toString((char) ch)));
    }

}

StringEscapeUtils를 사용하기 위해 commons-text 의존성을 추가해준다.

    implementation 'org.apache.commons:commons-text:1.8'
  1. Config
private final ObjectMapper objectMapper;

    @Bean
    public MappingJackson2HttpMessageConverter jsonEscapeConverter() {
        ObjectMapper copy = objectMapper.copy();
        copy.getFactory().setCharacterEscapes(new HTMLCharacterEscapes());
        return new MappingJackson2HttpMessageConverter(copy);
    }

참고 : https://jojoldu.tistory.com/470

profile
백엔드 개발자를 꿈꾸며 공부한 내용을 기록하고 있습니다.

0개의 댓글