XSS?

2024. 1. 24. 14:13Project

XSS(Cross Site Scripting)

  • 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법으로
  • XSS를 통해 사용자의 쿠키나 세션등의 민감한 정보를 탈취할 수 있다.

Stored XSS

  • 악의적인 사용자가 어떤 사이트에서 게시글을 작성할 때, 해당 게시글을 조회한 회원의 쿠키 정보를 탈취하는 악성 스크립트를 작성해서 저장했다고 가정하자.
  • 이후, 사용자가, 악성 스크립트가 저장되어있는 게시글을 클릭하면, 게시글이 열리면서 스크립트 코드가 실행이 될 것이다.
  • 이렇게 되면, 스크립트 코드를 통해서 사용자의 쿠키정보를 악의적인 사용자한테 전달할 것이다.
  • 악의적인 사용자는 해당 쿠키를 통해서 서버의 사용자인척하여 악의적인 행동을 할 것이다.
  • 만약 탈취한 쿠키가 관리자 회원의 쿠키였다면, 더욱 심각한 상황이 발생할 것이다.

XSS를 방어하는 방법

  • 오픈소스 "lucy-xss-servlet-filter"를 이용하여 서버로 들어오는 파라미터에 대해서 필터링을 하는 역할을 한다.
  • 예를 들어, 스크립트 코드를 작성할 때 사용하는 '<'문자는 '$lt'로 변환을 해준다.
  • 장점 ) 이렇게 되면, 사용자가 게시글을 열어도 서버에 저장된 문자가 치환되어 저장되기 때문에 JS코드가 실행되지 않을 것이다.
  • 단점 ) "lucy-xss-servlet-filter"는 application/x-www-form-urlencoded"에 대해서만 적용되고 http request body에 담긴 json데이터에 대해 처리해주지 못한다.
  • 따라서, json데이터를 필터 처리해주는 MappingJackson2HttpMessageConverter를 Bean으로 등록한다.

 

json데이터에도 XSS방지를 하기 위해 실제 프로젝트에 적용해보자.

build.gradle에 아래 의존성을 추가한다. 

implementation 'org.apache.commons:commons-text:1.8'

 

CharcterEscapes를 상속받는 HtmlCharcterEscapes클래스를 추가한다. 

public class HtmlCharacterEscapes extends CharacterEscapes {

    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;
    }

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

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

}

 

WebConfig에 configureMessageConverters 및 jsonEscapeConverter를 구현해준다.

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

    private final AuthenticationInterceptor authenticationInterceptor;
    private final MemberInfoArgumentResolver memberInfoArgumentResolver;
    private final AdminAuthorizationInterceptor adminAuthorizationInterceptor;
    private final ObjectMapper objectMapper;

    .
    .
    .
    
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(jsonEscapeConverter());
    }

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

}

  •  위와 같이 json데이터에 대해서도 다른 문자로 치환되어 XSS방지를 해줄 수 있음을 확인하였다.