XSS?
2024. 1. 24. 14:13ㆍProject
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방지를 해줄 수 있음을 확인하였다.
- 참조블로그
- 오픈소스 "lucy-xss-servlet-filter"
'Project' 카테고리의 다른 글
오프셋 기반 페이지네이션 vs 커서기반 페이지네이션 (0) | 2024.02.22 |
---|---|
Refresh Token을 redis에 저장한 이유? (0) | 2024.01.26 |
QueryDSL을 도입한 이유 (0) | 2024.01.25 |
cookie, session, jwt (0) | 2024.01.16 |
Oauth개념 및 동작방식 (0) | 2024.01.15 |