* Portfolio 카테고리에 포스팅한 글들은 경력기술서나 포트폴리오에 첨부한 프로젝트 관련되어 작성한 내용임을 알립니다.
* 내용에 대한 댓글은 언제나 환영입니다.
❗ 사내 보안 취약점 대응 포스팅은 #2 사내 보안 취약점 대응1 - 패킷 파라미터 변조 / #3 사내 보안 취약점 대응2 - XSS 및 서버 정보 노출 두개의 포스팅으로 나뉘어져 있습니다.
이전 글 링크 : https://fadet-coding.tistory.com/98
1. 관련 프로젝트 및 업무 개요
* 사내 진행했던 프로젝트로 github repository나 실제 프로덕트 코드는 비공개이며 포스팅의 모든 사항은 공개 가능한 범위에서만 작성합니다.
프로젝트 및 업무 명(공개 가능)
사내 보안 취약점 분석 및 수정
개발 환경(공개 가능)
Vue.js 2.x
intelliJ
JAVA 1.8 / Spring Boot 2.7.x / myBatis 2.x
Fiddler Classic / BurpSuite
Tomcat / Jenkins / Azure Kubernetes Service
2. 문제 분석 및 최초 Revision
* 포스팅에 사용된 코드 및 이미지는 실제 프로덕트에 사용되지 않은 전부 예시임
문제사항
보안 보고서를 기반으로 현재 내부 시스템 취약점 분석 및 수정 요구
단, 현실적으로 모든 OWASP 권고 사항에 대한 이행은 불가능하므로 critical한 취약점에 대한 수정 진행
(이번 포스트에서 2,3번 항목에 대해 기술, 1번은 이전 포스트 참조)
1 특정 수정 및 삭제 비즈니스 로직에서 HTTP 요청 패킷의 쿼리 파라미터 변조시 타 유저 데이터 변경 가능
2 클라이언트 input에 XSS 공격 시도시 악의적인 script 작동 (이번 포스트)
3 특정 url 요청시 WAS 서버 정보 노출 (이번 포스트)
근거
# (1-3 공통) BurpSuite 분석
# (1-2 공통) fiddler debugging을 사용한 모의 해킹 시도
# (3) 특정 URL 접속시 서버 정보 노출(staging, production 공통)
분석
1 HTTP 요청 패킷의 서버 수신 성공으로 인한 검증 로직 부재 의심
> WAS에 파라미터 검증 로직 존재 x
2 네트워크 통신 패킷 진입 전 클라이언트 submit부터 <script ... 코드 필터링 제외 (이번 포스트)
> Vue.js 기반 클라이언트의 v-html 태그의 XSS 공격 취약점 발견
3 특정 URL의 에러 발생 시점이 dispatcher servlet 진입 이전임을 확인 (이번 포스트)
> staging, production 내부 server.xml의 VALVE 설정 변경을 통해 서버 정보 노출 레벨 조정 가능
논의 및 학습
#2 클라이언트 input에 XSS 공격 시도시 악의적인 script 작동
해당 XSS 취약점은 JSP와 Vue.js 클라이언트 모두 발생했으므로 업무상 중요도를 고려하여 Vue.js 관련 항목 먼저 파악을 시작하여 아래 순서로 논의 후 적용 방식 결정
2-1 Vue.js로 작성된 클라이언트에 XSS 공격이 가능한가?
기존 알고있던 지식으론 Vue.js로 작성된 클라이언트 페이지는 input 자동 이스케이프를 통해 XSS 공격이 불가능한 것으로 알고 있었음
하지만 추가 확인 결과 Vue.js 템플릿 내 v-html 태그는 input 자동 이스케이프가 되지 않아 XSS 공격이 가능
2-2 그렇다면 v-html을 v-text나 {{}}같은 mustache로 변경하면 간단하지 않나?
근본적으로
1 v-html은 innerHTML
2 v-text는 textContent이며 {{}} 역시 Vue.js가 자동으로 escape처리를 진행해줌
2-3 JSP의 스크립틀릿이나 EL 태그를 JSTL의 c:out으로 변경하면 간단하지 않나?
1 Vue.js의 경우와 동일하게 innerHTML 기반으로 작동해야만 하는 요소는 c:out 태그와 사용 목적이 애초에 다르며 <c:out>은 v-text와 더 유사
2 거기에 더해 JSP는 Vue와 다르게 기본적으로 이스케이프 처리를 제공하지 않음
> 최종 논의 결과
@Vue.js
1 v-text나 {{}}로 사용해도 무방한 요소라면 수정 가능
2 위의 경우가 아니라면 vue-dompurify-html 라이브러리를 사용하여 escape
* sanitize를 통한 필터링은 사용하지 않았으므로 스킵
@JSP
1 <c:out> 태그를 사용 가능한 요소의 경우 변환시 escapeXml="false" 옵션을 추가하여 수정 가능
2 위의 경우가 아니라면 OWASP Java HTML Sanitizer 라이브러리를 사용하여 escape 및 sanitize
#3 특정 url 요청시 WAS 서버 정보 노출
WAS로 톰캣을 사용하는 경우 기본적으로 서블릿 컨테이너를 통과한 이상 요청은 web.xml 설정을 통해 에러 페이지가 서빙이 되지만 이 항목은 아니므로 아래 순서로 논의 후 적용 방식 결정
3-1 에러가 발생하는 특정 URL들의 공통점은 무엇인가?
보안 관련된 사항이므로 요구사항의 URL을 특정하여 밝힐 수는 없지만 서블릿 컨테이너 진입 전, 즉 애플리케이션 레벨에서 핸들링 불가능한 경우(예를 들어, 요청 헤더/바디 파싱 불가나 SSL Handshake, 인증서 검증 실패 등)
톰캣 내부 web.xml, 애플리케이션 내 @ControllerAdvice, ExceptionHandler가 처리하지 못함
3-2 컨테이너 기본 이미지에 포함된 server.xml 설정만 변경하면 간단한 작업 아닌가?
문제가 발생한 관리자 페이지의 사내 파이프라인은 부트의 내장 톰캣이 아닌 로컬, 개발, 배포 환경 각각 별도의 외장 톰캣을 사용했으므로 적용되는 server.xml을 모두 따로 찾아 수정해야만 했음
* 로컬의 경우 요구사항 밖이었지만 비교적 간단한 부분이며 추후 타 개발자의 유지보수시 혼란 방지를 위하여 함께 수정
> 최종 논의 결과 : 내부 server.xml의 VALVE 설정 변경
3. 결과
개선사항
#2 클라이언트 input에 XSS 공격 시도시 악의적인 script 작동
@ Vue.js
<!-- as-is -->
<div v-html="userInput"></div>
<!-- to-be -->
<div v-text="userInput"></div>
<div>{{ userInput }}</div>
<!-- sanitize 라이브러리 적용 -->
<div v-dompurify-html="richText"></div>
@JSP
<!-- as-is -->
<div><%= request.getParameter("userInput") %></div>
<div>${userInput}</div>
<!-- c:out 태그 사용 -->
<div><c:out value="${userInput}" escapeXml="false"/></div>
<!-- OWASP Java HTML Sanitizer 사용 (라이브러리 적용을 위한 pom.xml 및 부트 로직 생략) -->
<div><%= SanitizerUtil.sanitize(request.getParameter("comment")) %></div>
* sanitizer시 script 태그를 포함한 img 태그 멀티미디어, 폼 입력, 이벤트 계열 태그 모두 포함
#3 특정 url 요청시 WAS 서버 정보 노출
@a 로컬
Configuration에 등록된 외장 톰캣 디렉토리의 server.xml 변경
@b 개발
{ $CATALINA_HOME }/usr/local/tomcat/conf/server.xml 내부 valve
<Host ...>
...
<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false"/>
* 특정 에러 페이지를 반환하려면 ErrorReportValve 대신 CustomValve를 생성해야 함
@c 배포
* 사내 정보 노출 우려로 비공개
server.xml의 절대 경로 자체가 개발과 달랐으며 최상위 환경 변수 시작 디렉토리도 달랐으나
개발과 동일하게 적용되는 경로의 server.xml 정보 수정
* 컨테이너 자체가 아닌 이미지 빌드 파이프라인 내부 server.xml을 변경해야 함
테스트
2 클라이언트 input에 XSS 공격 시도시 악의적인 script 작동
# BurpSuite를 통해 악의적인 스크립트 삽입시
위와 같이 script 태그 escape 처리 완료
* 업무 대부분 fiddler를 사용했으나 최종 통과를 위해 BurpSuite도 동시 확인(fiddler도 마찬가지로 통과)
* Vue.js, JSP 페이지 모두 escape 확인 완료했으나 방식이 동일하므로 이미지 제외
3 특정 url 요청시 WAS 서버 정보 노출
# 보안 취약점 보고서에 명시된 특정 URL 삽입시
* 포스트 중간에 언급한대로 커스텀 에러 페이지 반환을 위한 valve 생성이 권장
4. 추후 이슈 및 대응
이슈 발생 사항
해당 없음
추가 고려 사항
1 포스팅에 언급했듯 커스텀 에러 페이지 반환을 위해 customValve로의 수정이 필요
2 XSS 취약점 분석 이후 회고 과정에서 CSRF 공격 가능성도 발견했으나 업무 기간 문제로 인해 추후 점검 예정
'Portfolio' 카테고리의 다른 글
#4 실무 IntelliJ+Git 사용 (0) | 2025.09.07 |
---|---|
#2 사내 보안 취약점 대응 1 (0) | 2025.09.05 |
#1 CompletableFuture를 이용한 비동기화 (0) | 2025.09.04 |