1. 서론
2. 적용 방법
3. 결과
적용했던 코드
https://github.com/GHGHGHKO/roadmap-todo/commit/2b7f2543df849704f9784d3afc818ae07db72ef8
1. 서론
회사에서 최근에 시작한 프로젝트에 보안 검사를 받았습니다.
Request body를 통한 크로스사이트 스크립트 취약점이 도출 되었습니다.
도출되었던 방식은
1. a_dns API Request body에 악성 script를 심어서 전송합니다.
2. database에는 악성 script가 입력됩니다.
3. 일반 고객이 b_dns 로 홈페이지에 접속합니다.
4. 악성 script가 들어가 있는 정보를 조회합니다.
5. 악성 script가 db에서 조회되어 고객에게 보여집니다.
6. 해당 스크립트가 웹사이트에서 실행됩니다.
크로스사이트 공격은 사진과 같이 이루어집니다.
1. 해커가 Request body 혹은 Query String에 악성 스크립트를 입력합니다.
2. 사용자는 평소처럼 웹사이트에 접속합니다.
3. 웹사이트에 접속할 때 해커가 심어놓은 악성 스크립트가 실행됩니다.
예를 들어
<script>alert('alice is a lice')</script>
요런 스크립트를 심어놓으면
웹사이트에 들어갈 때마다 저런 alert이 뜨게됩니다.
alert은 그저 장난일 수 있지만
https://hackmd.io/@ephemeral-instance/r1djIS-Hd
요 웹사이트에 나와있는 예시처럼 악성 스크립트를 삽입하게 되면
엘리스 사진이 아니라 과거 2xch 처럼 변경할 수도..?
서론이 길었네요 껄껄
2. 적용 방법
오류를 먼저 만들어봅시다.
(웹사이트가 없어서 그냥 백엔드에서만)
curl --location 'localhost:8080/todos' \
--header 'Content-Type: application/json' \
--data '{
"title": "<script>alert('\''alice is a lice'\'')</script>",
"description": "Buy milk, eggs, and bread"
}'
이렇게 호출하게 되면
insert into users_todos (created_b ..중략.. '00','<script>alert(''alice is a lice'')</script>','62ede1f8-f24c-4575-bd7a-0807f8ffc6e1',1);
이렇게 스크립트가 입력됩니다.
이제 웹사이트에서 users_todos 테이블을 조회한 뒤 보여주면
스크립트가 실행 될겁니다.
jsoup 으로 스크립트 치환하기
이제 본론입니다.
우선 종속성을 추가합니다.
https://mvnrepository.com/artifact/org.jsoup/jsoup
implementation("org.jsoup:jsoup:1.18.2")
우리의 목적은
Request body로 부터의 악성 script를 막기 위함이니
Request body -> DTO 파싱되는 부분을 변경해야 합니다.
ObjectMapper Bean을 선언합니다.
deserialize 함수를 override하여
valueAsString 값을 Jsoup의 clean 함수로 html tags를 정리합니다.
정리하는 값들은 Safelist.basic() 안에 들어있습니다.
basic이 아닌 다른 함수를 사용해도 무방합니다. 고건 찾아보세여
요 변수를 registerModule 함수를 통해 등록합니다.
설정은 끝났습니다.
이제 테스트를 해봅시다.
3. 결과
Request
curl --location 'localhost:8080/todos' \
--header 'Content-Type: application/json' \
--data '{
"title": "\"<script>alert('\''alice is a lice'\'')</script>", # 구분을 위해 \"을 추가했습니다.
"description": "Buy milk, eggs, and bread"
}'
요렇게 요청을 해봅니다.
Response
{
"id": 1,
"title": "\"",
"description": "Buy milk, eggs, and bread"
}
<script>alert('alice is a lice')</script>
요 코드는 지워지고
title field에 \" 만 남은걸 확인 할 수 있습니다.
데이터베이스에는
insert into users_todos (created ..중략.. ,'"','1621cf73-d7c2-4b9a-8d39-d140b239f521',2);
title field에 " 값만 입력됐네요
이제 b_dns에서 users_todos 테이블을 호출해도
스크립트가 실행되진 않을겁니다.
끝
'SpringBoot' 카테고리의 다른 글
GraalVM 으로 SpringBoot 시작 시간 줄이기 (맛보기) (0) | 2024.03.27 |
---|---|
RequestParam(required = true) null exception 하는 법 (0) | 2022.10.05 |
jib 배포, 코드 배포, 코드 컨테이너, 앱 컨테이너 만들기 (0) | 2022.07.15 |
String, StringBuilder, StringBuffer 사용법 및 차이 (0) | 2021.12.23 |
통신 중 실패했을 때 재시도하기 (@Retryable, @Recover) (0) | 2021.12.22 |