크로스 사이트 스크립팅(XSS) 방지하기: `<c:out>` 태그 활용하기

신수정·2024년 5월 11일
0

이번 포스팅에서는 크로스 사이트 스크립팅(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 공격을 방지합니다.

특수 문자이스케이프 처리 결과
&&amp;
<&lt;
>&gt;
"&quot;
'&#039;

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 페이지

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> 태그 활용 시 주의사항

  1. 미리 이스케이핑된 데이터: 이미 이스케이핑된 데이터를 <c:out> 태그로 출력할 경우, HTML 이스케이핑이 중복되어 내용이 깨질 수 있습니다.
  2. 보안에 대한 과도한 신뢰: <c:out> 태그만으로는 XSS 공격을 완전히 방지할 수 없기 때문에, 백엔드에서도 데이터 검증이 필요합니다.

마치며

크로스 사이트 스크립팅(XSS) 공격은 웹 애플리케이션의 보안에 큰 위협이 될 수 있습니다. 이번 포스팅에서 소개한 <c:out> 태그는 JSP 기반의 웹 애플리케이션에서 XSS 공격을 방지하는 유용한 도구이지만, 완벽한 해결책은 아닙니다. 백엔드 로직에서도 데이터 검증 및 이스케이핑을 철저히 해야 하며, 콘텐츠 보안 정책(CSP) 등을 적극 활용하는 것도 추천드립니다.

참고 자료

profile
안녕하세요:)

0개의 댓글