생산성을 향상시키는 스프링부트 기반의 API 템플릿 프로젝트 구현 강의를 듣고 정리한 내용입니다.
XSS(Cross Site Scripting)
악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법
쿠키나 세션 등 민감한 정보를 탈취할 수 있다.
저장형 XSS
- 악의적인 사용자가 사이트에 악성 스크립트를 작성해서 저장함. ( <script>나쁜코드</script> )
- 사용자가 악성 스크립트가 저장되어있는 웹사이트에 접속함,
- 스크립트 코드가 실행되고, 사용자의 정보가 악의적인 사용자한테 전달됨,
- 악의적인 사용자가 서버에 사용자인척 하며 악의적인 행동을 할 수 있음. 사용자가 관리자였다면 더 큰 피해가 발생!
따라서 코드가 삽입되지 못하도록 막아야한다!
= '<', '>'와 같은 문자들을 '<', '>' 로 변경하면 됨! → 치환되어 저장되기 때문에 자바스크립트가 실행되지 않음.
XSS 방어
XSS 방어를 위해 네이버에서 제작한 lucy-xss-servlet-filter를 사용한다.
https://github.com/naver/lucy-xss-servlet-filter
GitHub - naver/lucy-xss-servlet-filter
Contribute to naver/lucy-xss-servlet-filter development by creating an account on GitHub.
github.com
그러나 lucy-xss-servlet-filter는 application/x-www-form-urlencoded에 대해서만 적용되고 http request body에 담긴 json데이터에 대해서는 처리되지 않는다.
→ json 데이터를 필터처리해주는 MappingJackson2HttpMessageConverter 빈 등록
(참고 : https://jojoldu.tistory.com/470)
Spring Boot에서 JSON API에 XSS Filter 적용하기
일반적인 웹 애플리케이션에서 기본적으로 해야할 보안으로 XSS 방지가 있습니다. 기존에 많이들 알고 계시는 lucy filter의 단점은 이미 오명운 님께서 잘 정리해주셨기 때문에 한번쯤 읽어 보셔
jojoldu.tistory.com
XSS 방어 설정이 되어있지 않은 경우
스크립트의 내용이 그대로 반환되고 있다. 이제 이 코드들을 '<' 와 같은 문자들로 치환해 줄 것이다.
application/x-www-form-urlencoded 방어 설정
1. build.gradle에 의존성을 추가해준다.
implementation 'com.navercorp.lucy:lucy-xss-servlet:2.0.0'
2. resource 폴더에 아래 두 xml 파일을 추가해준다.
3. WebConfig에 Bean으로 등록한다.
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
// 앞의 코드들은 다른 코드들이라서 생략
@Bean
public FilterRegistrationBean<XssEscapeServletFilter> filterRegistrationBean() {
FilterRegistrationBean<XssEscapeServletFilter> filterRegistration = new FilterRegistrationBean<>();
filterRegistration.setFilter(new XssEscapeServletFilter());
filterRegistration.setOrder(1);
filterRegistration.addUrlPatterns("/*");
return filterRegistration;
}
}
4. 끝! 이제 x-www-form-urlencoded로 오는 요청에는 '<', '>' 와 같은 특수문자들이 변환되어 반환된다.
application/json 방어 설정
1. build.gradle에 의존성을 추가해준다.
implementation 'org.apache.commons:commons-text:1.10.0'
*강의에서는 1.8버전인데 인텔리제이에서 1.8버전에 취약점이 있다고 경고가 떴다. https://mvnrepository.com/artifact/org.apache.commons/commons-text 를 참고해서 1.10.0 버전으로 추가했다.
2. CharacterEscapes를 상속받은 HtmlCharacterEscapes 클래스를 생성한다.
package com.app.global.config.web;
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() {
// 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)));
}
}
3. WebConfig에 등록한다.
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
// 관련 없는 코드 생략
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);
}
}
4. 끝! 이제 JSON으로 요청하는 경우에도 '<', '>' 와 같은 특수문자들이 변환되어 반환된다.
'Study > Spring' 카테고리의 다른 글
[Spring] 제어의 역행과 의존관계 주입(IoC, Dependency Injection) (1) (0) | 2023.04.18 |
---|