이번 포스팅에서는 크로스 사이트 스크립팅(XSS) 공격을 방지하기 위한 방법 중 하나인 <c:out>
태그에 대해 살펴보겠습니다. <c:out>
태그는 JSP(JavaServer Pages)에서 제공하는 JSTL(JavaServer Pages Standard Tag Library)의 일부로, HTML 이스케이핑을 통해 XSS 공격을 방지할 수 있습니다.
<c:out>
태그란?<c:out>
태그는 JSTL 코어 라이브러리의 태그로, JSP에서 데이터를 출력할 때 사용됩니다. 이 태그의 가장 큰 특징은 자동으로 특수 문자를 이스케이프하여 XSS 공격을 방지한다는 점입니다.
<c:out>
태그 사용 예시기본적인 사용법은 다음과 같습니다.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<c:out value="${post.title}" />
위 코드는 ${post.title}
에 포함된 HTML 특수 문자를 이스케이프하여 안전하게 출력합니다.
<c:out>
태그의 기본 동작<c:out>
태그는 다음과 같은 특수 문자를 HTML 이스케이프 처리하여 XSS 공격을 방지합니다.
특수 문자 | 이스케이프 처리 결과 |
---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
BoardAPIController
에서 <c:out>
활용하기BoardAPIController
의 데이터를 JSP 페이지에 출력할 때 <c:out>
태그를 활용하여 안전하게 데이터를 표시해 보겠습니다.
BoardAPIController
클래스게시글 데이터를 조회하여 JSP 페이지로 전달합니다.
package com.moonBam.controller.board;
import com.moonBam.dto.MemberDTO;
import com.moonBam.dto.board.PostPageDTO;
import com.moonBam.service.PostService;
import com.moonBam.service.member.MemberLoginService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.util.Map;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/post")
public class BoardAPIController {
private final PostService postService;
private final MemberLoginService memberLoginService;
@GetMapping("/{postId}")
public ResponseEntity<?> findOne(@PathVariable("postId") Long postId, Principal principal){
PostPageDTO pDTO = postService.selectPagePost(postId);
if (pDTO == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of("message", "존재하지 않는 게시글입니다."));
}
MemberDTO loginUser = memberLoginService.findByPrincipal(principal);
boolean isAuthorized = loginUser != null && loginUser.getUserId().equals(pDTO.getUserId());
return ResponseEntity.ok(Map.of("pDTO", pDTO, "isAuthorized", isAuthorized));
}
}
JSP 페이지에서 <c:out>
태그를 사용하여 안전하게 데이터를 표시합니다.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>게시글 상세보기</title>
</head>
<body>
<h1>게시글 상세보기</h1>
<div>
<label>제목:</label>
<c:out value="${pDTO.postTitle}" />
</div>
<div>
<label>작성자:</label>
<c:out value="${pDTO.nickname}" />
</div>
<div>
<label>내용:</label>
<c:out value="${pDTO.postText}" />
</div>
<div>
<label>작성일:</label>
<fmt:formatDate value="${pDTO.createdDate}" pattern="yyyy-MM-dd HH:mm:ss" />
</div>
</body>
</html>
<c:out>
태그 활용 시 주의사항<c:out>
태그로 출력할 경우, HTML 이스케이핑이 중복되어 내용이 깨질 수 있습니다.<c:out>
태그만으로는 XSS 공격을 완전히 방지할 수 없기 때문에, 백엔드에서도 데이터 검증이 필요합니다.크로스 사이트 스크립팅(XSS) 공격은 웹 애플리케이션의 보안에 큰 위협이 될 수 있습니다. 이번 포스팅에서 소개한 <c:out>
태그는 JSP 기반의 웹 애플리케이션에서 XSS 공격을 방지하는 유용한 도구이지만, 완벽한 해결책은 아닙니다. 백엔드 로직에서도 데이터 검증 및 이스케이핑을 철저히 해야 하며, 콘텐츠 보안 정책(CSP) 등을 적극 활용하는 것도 추천드립니다.
참고 자료