JSP에서 데이터를 출력할 때 <c:out> 태그를 사용하면 HTML 태그가 문자열 그대로 출력되는 경우가 있다.
<c:out value="${conts.ttl}"/>
예를 들어 위와 같은 코드가 있는데, 만약 conts.ttl 값이 아래와 같다면
"제목입니다.<br>다음 줄입니다."
브라우저에서는 <br> 태그가 적용되지 않고, 그대로 제목입니다.<br>다음 줄입니다. 처럼 보일 것이다.
이것은 <c:out>이 기본적으로 HTML을 이스케이프 처리하기 때문이다.
◆ <c:out>의 기본 동작
JSP에서 <c:out> 태그는 XSS(크로스 사이트 스크립팅) 공격을 방지하기 위해 기본적으로 HTML을 이스케이프 처리한다.
즉, HTML 태그를 문자열 그대로 출력하도록 동작한다는 것이다.
예를 들어 c:out을 사용하면 다음과 같이 변환되는데, 이러한 동작 때문에 HTML 태그가 정상적으로 렌더링 되지 않고 문자 그대로 출력되는 문제가 발생한다.
원래 값 | <c:out> 출력 결과 |
<b>굵은 텍스트</b> | <b>굵은 텍스트</b> |
Hello<br>World | Hello<br>World |
◆ 해결 방법
<c:out> 태그에 escapeXml="false" 속성을 추가해서 문제를 해결할 수 있는데
이렇게 하면 아래와 같이 conts.ttl 값에 포함된 HTML 태그가 정상적으로 렌더링 되고,
브라우저에서 HTML태그로써 정상적으로 적용되어 줄바꿈이 이루어진다.
<c:out value="${conts.ttl}" escapeXml="false"/>
<적용 전 결과 (기본동작)>
제목입니다.<br>다음 줄입니다.
<적용 후 결과 (escapeXml="false" 속성 사용)>
제목입니다.
다음 줄입니다.
◆ escapeXml="false" 사용 시 주의할 점
HTML을 그대로 출력할 경우, 보안적인 문제가 발생할 수 있다.
<script>alert('해킹!');</script>
사용자가 입력한 값에 <script> 태그가 포함되어 있다면, 악성 스크립트가 실행될 가능성이 있기 때문에 사용자 입력값을 직접 출력할 때는 악성 스크립트 삽입(XSS) 공격을 방지하기 위해 신뢰할 수 있는 입력값인지 검증하는 것이 중요하다.
필터링을 거쳐 안전한 태그만 허용하는 것도 하나의 방법이 될 것이다.
글 내용 중 잘못된 부분이 있거나, 첨부하실 내용이 있으시면 댓글로 남겨주세요. 공부하는데 많은 도움이 됩니다.
-- 기억의 유효기간은 생각보다 짧다. --