이번에는 시큐어코딩을 하기위한 XSS 를 예방하는 코드에 대해서 정리를 할 것이다.
XSS(Cross-site scripting) 란?
XSS 는 웹 애플리케이션에서 많이 나타나는 취약점 중 하나로, 공격자가 신뢰할 수 있는 응용 프로그램이나 웹 사이트의 코드에 악성 실행 가능 스크립트를 삽입하는 공격이다.
공격자는 종종 사용자에게 악성 링크를 보내고 사용자가 링크를 클릭하도록 유도하여 XSS 공격을 시작한다.
앱이나 웹사이트에 적절한 데이터 삭제가 없는 경우 악성 링크는 공격자가 선택한 코드를 사용자 시스템에서 실행하고,
결과적으로 공격자는 사용자의 활성 세션 쿠키를 훔칠 수 있게 된다.
- XSS 공격 유형
1. Reflected XSS
: 악성 스크립트가 웹 애플리케이션에서 피해자의 브라우저로 반영될 때 발생.
악의적인 링크를 배포하기 위해 가해자는 일반적으로 이메일 또는 타사 웹사이트에 링크를 삽입한다.
2. Stored XSS
: 취약한 웹 애플리케이션에 악성 코드를 주입하는 공격 기법.
악성 코드가 데이터베이스에 같이 저장되어, 사용자가 해당 데이터를 조회할 때마다 악성 코드가 실행된다.
XSS in Thymeleaf
예제를 구현하기위해 간단하게 게시판을 만들어 게시글 내용에 '<script>alert('hi');</script>'를 저장했다.
아무런 조치를 하지 않았는데도 값이 정상적으로 나와 당황스러웠다.
알고보니, Thymeleaf 에서 th:text 와 [[..]] 에서 기본적으로 이스케이프 기능을 지원한다고 한다.
공식문서에서 확인할 수 있으며 '<' 와 같은 특수문자를 HTML 엔티티로 변경하는 것을 이스케이프(Escape)라 한다.
위의 화면에서 소스 보기를 하면 이스케이프 된 내용을 확인할 수 있다.
( 이스케이프되는 것이 싫으면 th:utext 로 사용하면 된다. )
DB에는 특수문자로 저장이된다. ( ex> <script>alert('hi');</script> )
XSS Prevention with XSS Filter
직접 XSSFilter를 구현하여 해당 메서드로 값을 치환할 수도 있다.
public class XSSFilter {
public static String xssReplace(String str) {
str = str.replaceAll("&", "&");
str = str.replaceAll("\"", """);
str = str.replaceAll("'", "'");
str = str.replaceAll("<", "<");
str = str.replaceAll(">", ">");
str = str.replaceAll("\r", "<br>");
str = str.replaceAll("\n", "<p>");
return str;
}
}
그러면 아래와 같이 script가 텍스트로 출력된다.
또한, DB에 저장할 때 치환된 값이 저장된다.
XSS Prevention with spring security
spring security 에서 제공하는 xssProtection()를 사용하면 refelcted XSS 를 예방할 수 있다.
@Configuration
@EnableWebSecurity
public class WebSecurityConfig{
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.headers()
.xssProtection()
.and()
.contentSecurityPolicy("script-src 'self'");
return http.build();
}
}
해당 설정을 마치고 <script>alert('hi');</script> 와 <h2>HI!</h2> 를 내용에 저장하여 테스트를 해봤다.
테스트 결과, alert는 실제로 alert 창이 발생하지 않지만 HI! 는 h2의 태그가 먹혀 출력되는 것을 확인할 수 있었다.
추가적으로 a태그로 링크도 저장해보았지만 내용이 확인되지는 않았다.
DB에 저장된 값은 아래와 같으며, 페이지 소스보기를 통해 확인한 결과도 이하동일하다.
즉, 위의 설정을 통해 Reflected XSS 를 막을 수는 있지만, 다른 XSS 공격에 대비하기 위해 자체적인 필터를 추가하는 것이 필요해보인다.
참고
https://www.ibm.com/garage/method/practices/code/protect-from-cross-site-scripting/
https://www.synopsys.com/glossary/what-is-cross-site-scripting.html
https://code0xff.tistory.com/100
https://www.imperva.com/learn/application-security/reflected-xss-attacks/
'Web' 카테고리의 다른 글
[Spring] Maven Scope 와 Gradle Configurations (0) | 2023.08.27 |
---|---|
[Spring] compiletime 과 runtime 에 대해서 (0) | 2023.08.13 |
[Spring] Unit Tests with Mockito ( in Service Layer ) (0) | 2023.07.25 |
[Spring] MapStruct 사용하기 (0) | 2023.07.08 |
[Spring] 라이브러리 버전 관리하기 ( Gradle ) (0) | 2023.07.06 |