개발 일상(Dev)

jstl _ <c:out> 을 사용하는 이유와 XSS(크로스 사이트 스크립팅)

Roovelo 2023. 4. 4. 17:22

Sparrow 도입과 XSS


최근에 “Sparrow SAST” 라고 하는 소스코드 보안 취약점 점검 솔루션을 도입하고 테스트 및 사용을 해보고 있습니다.

이 솔루션으로 프로젝트를 전체적으로 검사를 해봤는데요. 가장 많이 발견되는 취약점이 XSS(크로스 사이트 스크립팅) 더라고요. 그리고 이 XSS 중에서도 가장 많이 검출되는 부분이 el태그 를 사용하는 부분이었습니다.

${siteId}  
//이렇게 ${값} 형식으로 jsp 에서 사용하는 부분은 모두 취약하다고 검출됨

el태그 를 사용하는 부분이 취약점으로 검출되는지 알아보니까 이 태그를 이용해서 출력을 할 때 출력값 안에 스크립트가 있다면 해당 스크립트가 실행이 된다고 하네요.

예를 들어 “회원가입 아이디 입력” 부분의 input type=“text” 에 값을 입력하고 그 다음 화면에서 “가입 완료, 아이디 : ${id}” 이런식으로 화면이 표출된다고 할 때 아이디에다가 정상적인 아이디 대신 아래와 같은 스크립트를 입력하면 스크립트가 실행이 되는겁니다.

<script>alert(“XSS”);</script>

스패로우에서 추천하는 해결책


이 문제에 대해서 스패로우 솔루션에서 추천하는 해결 방법은 해당 값에 대해서 필터링을 설정하라는 내용이었는데요. 저희 회사에서는 이미 ESAPI네이버 루시 등을 이용해서 필터링을 하고 있는 상황이었습니다.

그러니까 이미 해결한 문제를 취약점이라고 검출하고 있더라고요.

그런데 스패로우는 “소스코드”를 확인하는 솔루션이기 때문에 다른 영역에서 처리되는 내용까지는 확인을 못해서 검출이 된다고 합니다. 솔루션 자체에는 예외 처리 같은게 있기 때문에 저 부분을 이미 처리했다고 예외처리를 하면 되는데요.

하지만 계속 이 솔루션을 사용해야 하는데 jsp 파일 하나하나 마다 다 저 취약점이 검출된다면 사용할 때 마다 예외처리를 하기가 많이 번거러울 것 같았습니다.

그래서 그럼 아에 소스코드 자체에서도 취약점이 아니라고 판단 되는 다른 방법이 또 있나? 하고 찾아봤는데요. 간단하게 jstl 을 이용해서, 그러니까 <c:out> 을 사용하면 된다고 하네요.

value = “${siteId}” //el 태그로 출력
value = “<c:out value=‘${siteId}’/>” // jstl core 태그 사용

이렇게 <c:out> 으로 출력을 변경 하고 솔루션을 다시 돌려보니까 취약점이 검출되지 않았습니다.

<c:out>은?


우선 <c:out> 이라는건 jstl 이라고 하는 자바서버 페이지 표준 태그 라이브러리(JavaServer Pages Standard Tag Library, 약칭 JSTL>에서 사용하는 변수 내용을 출력하는 태그 입니다.

JSTL에 대해서 정리를 할까 하다가 잘 정리해둔 블로그가 있어서 그냥 그 내용을 읽어보는게 제일 좋을 것 같더라고요. 아래 블로그에서 JSTL과 대강의 사용법들을 확인할 수 있습니다.

개발과 디자인 사이 - jstl의 기본 개념과 사용방법 정리

저는 <c:out> 에 대해서 알아보고 있어서 이 태그만 조금 더 알아봤는데요.

<c:out>으로 작성하면 들어오는 문자를 그대로 출력해주기 때문에 보안적으로 안전하다

예를 들어서 제목과 본문을 써서 게시판에 글을 적는 사이트가 있다고 했을 때 제목에다가 내용을 아래와 같이 작성.

제목 : <script>alert(‘11’);</script> 

후에 이 제목을 불러오는 화면에서 기존 el태그 를 사용하면 저 alert이 실행이 됩니다.

그러나 <c:out> 태그를 이용해서 출력을 하면 alert이 실행이 되는게 아니라 저 <script ~ 부분이 전부다 그냥 문자로 인식되어서 출력이 됩니다.

위의 예시에서는 alert 만 실행됐을 뿐이지만 결론적으로 사용자가 원하는 스크립트를 실행시킬 수 있다는 내용이기 때문에 해당 부분이 보안취약점이라고 솔루션에 검출되는 거라고 보면 되겠습니다.

그러니까 <c:out>은

html 코드가 들어있어도 코드를 해석하지 않고 문자로 인식하고 출력시킨다.

가 포인트 입니다.

<c:out> 의 속성값


그리고 <c:out> 에는 escapeXml 이라는 속성값이 있는데요.

<c:out value=“${siteId}” escapeXml=“true”>
<c:out value=“${siteId}” escapeXml=“false”>

이렇게 true, false 2가지 속성이 있고 true 인 경우가 값을 그냥 문자열로 출력하는 경우,

false 가 html 이 들어올 경우 그 html 을 해석하는 경우입니다. (false로 설정하면 script 가 있을 경우 실행)

default 값은 true 이기 때문에 생략이 가능합니다만 이걸 굳이 적는건 false 로 적겠다는 뜻이고 그렇게 되면 사실상 <c:out> 을 쓰는 의미가 없겠네요.

다만 의도적으로 html 태그를 해석해야할 필요가 있는 경우가 있어서 이 속성이 있다고 하네요.

홍<b>길동</b> 

예를들어서 위의 예시와 같이 이름에만 강조 표시 등을 주고 싶을 때 escapeXml 속성에다가 false 를 줘서 태그를 해석하게 만들어서 사용하는 것 같습니다. 그리고 당연히 이 속성을 false 로 사용할 때는 다른 필터링 솔루션이나 백단에서의 처리 로직 등을 통해서 별도의 취약점 문제를 해결해야 합니다.

728x90