Spring JSP에서 HTML Escape 사용하기

XSS(Cross-Site Scripting) 공격을 방지하기 위해 사용자 입력값을 HTML 엔티티로 변환하는 방법입니다. Spring 태그 라이브러리와 JSTL을 활용합니다.

1. Spring 태그 사용 (권장)

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<!-- htmlEscape 속성으로 이스케이프 -->
<spring:message code="msg.welcome" htmlEscape="true"/>

<!-- 특정 영역 전체 이스케이프 -->
<spring:htmlEscape defaultHtmlEscape="true"/>

<!-- 이후 모든 spring 태그에 적용 -->
<spring:message code="msg.content"/>

2. JSTL c:out 태그

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- 기본적으로 이스케이프 적용 -->
<c:out value="${userInput}"/>

<!-- 명시적으로 이스케이프 활성화 -->
<c:out value="${userInput}" escapeXml="true"/>

<!-- 이스케이프 비활성화 (HTML 허용 시) -->
<c:out value="${safeHtml}" escapeXml="false"/>

3. EL 표현식 직접 사용 시 (위험)

<!-- 위험: 이스케이프 안 됨 -->
<div>${userInput}</div>

<!-- 안전: c:out 사용 -->
<div><c:out value="${userInput}"/></div>

4. fn:escapeXml 함수

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!-- 속성 값에서 사용 -->
<input type="text" value="${fn:escapeXml(userInput)}"/>

<!-- JavaScript 문자열에서 -->
<script>
var name = "${fn:escapeXml(userName)}";
</script>

5. 전역 설정 (web.xml)

<!-- 모든 JSP에 기본 htmlEscape 적용 -->
<context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
</context-param>

6. 변환 예시

원본변환 후
<&lt;
>&gt;
&&amp;
"&quot;
'&#39;

7. XSS 공격 예방

<!-- 공격 입력 -->
userInput = "<script>alert(XSS)</script>"

<!-- 이스케이프 없이 (취약) -->
<div>${userInput}</div>
<!-- 결과: 스크립트 실행됨 -->

<!-- 이스케이프 적용 (안전) -->
<div><c:out value="${userInput}"/></div>
<!-- 결과: &lt;script&gt;... 텍스트로 표시 -->

8. 주의사항

  • 사용자 입력은 항상 이스케이프 처리
  • DB에서 가져온 데이터도 출력 시 이스케이프
  • HTML 에디터 등 HTML 허용 필요시 화이트리스트 방식 사용
  • JavaScript 내 변수는 추가 이스케이프 필요