코드잇 BE스프린트

위클리 페이퍼 - 14주차

beginner-development 2026. 4. 30. 21:58

Spring 기반 웹 애플리케이션에서 발생할 수 있는 4가지 주요 보안 공격 (CSRF, XSS, 세션 고정, JWT 탈취)에 대해 설명하고, 각각에 대한 Spring Security 또는 일반적인 대응 전략을 설명하세요.

1. CSRF

CSRF란?

CSRF는 사용자가 자신도 모르게 악성 사이트에서 원하지 않는 요청을 보내도록 속여 공격하는 방식입니다.
브라우저는 같은 사이트에 대해 자동으로 쿠키(세션)를 포함시켜 요청을 보낸다는 특성을 이용해 공격합니다.

예를 들어, 사용자가 이미 로그인한 상태에서 다른 악성 웹페이지를 방문했을 때, 악성 사이트가 사용자의 브라우저를 통해 "계좌 이체"와 같은 중요한 요청을 자동으로 보내게 합니다.

 

대응 전략

Spring Security에서는 기본적으로 CSRF 보호 기능을 제공합니다.

  • 기본 설정(활성화 상태, 별도의 설정 불필요)
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 
	http 
    	.csrf(csrf -> csrf 
        	.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 
        ) 
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) 
        .formLogin(withDefaults()); 
   return http.build();
}
  • 명시적 비활성화(REST API 등에서 필요할 경우만 비활성화)
@Bean 
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 
	http 
    	.csrf(AbstractHttpConfigurer::disable) 
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) 
        .formLogin(withDefaults()); 
        
   return http.build();
}

 

방어 원리

  • 서버는 요청을 받을 때 사용자 요청에 'CSRF 토큰'이라는 추가 정보를 요구함
  • 이 토큰은 사용자의 세션과 연결된 고유한 값이고, 클라이언트가 직접 HTML 폼이나 헤더에 넣어 전송해야 함
  • 즉, 공격자가 만든 악성 페이지는 이 토큰 값을 모를 수밖에 없기 때문에 요청이 거부됨

2. XSS

XSS란?

XSS는 공격자가 웹페이지에 악성 스크립트를 삽입하여 다른 사용자가 이 스크립트를 실행하도록 만드는 공격입니다.

예를 들어, 게시판이나 댓글 입력창에 악성 스크립트를 입력하면, 이 글을 보는 사용자의 브라우저에서 스크립트가 실행되어 개인정보 탈취 등의 피해가 발생합니다.

 

대응 전략

XSS는 주로 입력값 검증과 출력값 처리로 방어합니다.

 

입력값 처리

  • 모든 입력값을 철저히 검증합니다.
  • 특수문자 제한, 입력 길이 제한 등을 설정합니다. (스크립트 삽입을 막음)

출력값 처리

  • Thymeleaf 같은 템플릿 엔진을 사용하면 기본적으로 HTML 인코딩 처리됩니다.
<!-- Thymeleaf 예시 (자동으로 HTML 태그를 이스케이프 처리) --> 
<p th:text="${userInput}"></p>
  • REST API에서는 JSON 응답을 활용하여 스크립트 실행을 막을 수 있습니다.
<!-- XSS 안전 -->
<p th:text="${userInput}"></p>
→ 사용자가 `<script>` 입력해도 `&lt;script&gt;`로 표시됨
<!-- XSS 위험 -->
<p th:utext="${userInput}"></p>
→ script 실행됨

 

3. 세션 고정

세션 고정이란?

공격자가 사용자의 세션 ID를 미리 정해놓고(고정) 사용자가 해당 세션을 사용하도록 유도하는 공격입니다.

예를 들어, 공격자가 미리 만든 세션 ID를 사용자가 로그인 시 사용하게 만들어, 사용자의 세션을 탈취하거나 도용하는 것입니다.

 

대응 전략

Spring Security는 로그인 시 세션을 새로 생성하는 방식으로 기본 방어합니다.

  • Spring Security 기본 전략(세션 변경)
  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      http
          .sessionManagement(session -> session
              .sessionFixation(SessionManagementConfigurer.SessionFixationConfigurer::migrateSession)
          )
          .authorizeHttpRequests(auth -> auth.anyRequest().authenticated());

      return http.build();
  }
  • 다른 옵션들
    • migrateSession (기본값): 로그인 시 세션을 새로 생성하고, 기존 세션의 데이터를 복사합니다.
    • newSession: 완전히 새로운 세션을 생성하며, 기존 세션 데이터는 복사하지 않습니다.
    • changeSessionId: 세션 데이터는 유지하면서 세션 ID만 변경합니다.

4. JWT 탈취

JWT 탈취 공격이란?

JWT는 보통 인증에 쓰이는 토큰입니다. 토큰을 탈취하면 공격자는 이를 이용해 사용자인 척 할 수 있습니다.

예를 들어, JWT가 브라우저에 저장되어 있을 때, 악성 스크립트가 이 토큰을 빼내 공격자의 서버로 전송하면 공격자는 해당 사용자로 위장할 수 있습니다.

 

대응 전략

JWT는 본질적으로 탈취에 취약하므로, 여러 보안 전략을 통해 보호해야 합니다.

  • HTTPS 사용
    • 토큰이 네트워크를 통해 전송될 때 반드시 HTTPS를 사용해 암호화합니다.
  • 토큰 만료 기간 설정
    • 짧은 만료 시간을 설정하여, 탈취된 토큰을 장기적으로 사용하는 것을 방지합니다.
// 예시: 15분 만료 JWT 토큰 설정 (예: JJWT) 
Instant expiration = Instant.now().plus(15, ChronoUnit.MINUTES);
String token = Jwts.builder()
   .subject("userId")
   .expiration(Date.from(expiration))
   .signWith(key)
   .compact();
  • 리프레시 토큰 사용
    • 액세스 토큰의 유효 기간을 짧게 설정하고, 리프레시 토큰을 사용해 갱신합니다.
    • 리프레시 토큰은 반드시 HttpOnly 쿠키로 저장하여 JavaScript 접근을 막습니다.
ResponseCookie cookie = ResponseCookie.from("refreshToken", refreshToken)
    .httpOnly(true)
    .secure(true) // HTTPS 환경에서만 전송
    .path("/")
    .maxAge(Duration.ofDays(7))
    .build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
  • 토큰 서명 검증 및 무효화
    • Spring Security와 JWT 라이브러리를 통해 토큰 서명을 철저히 검증하고, 필요 시 블랙리스트를 통해 무효화 관리합니다.

나만의 언어로 정리해보기

4가지 주요 보안 공격
1. CSRF
-
사용자가 자신도 모르게 악성 사이트에서 원하지 않는 요청을 보내도록 속여 공격하는 방식

 대응 전략
- Spring Security에서는 기본적으로 CSRF 보호 기능을 제공한다.
원리
  -
 서버는 요청을 받을 때 사용자 요청에 'CSRF 토큰'을 요구함
  - 이 토큰은 사용자의 세션과 연결된 고유한 값이고, 클라이언트가 직접 넣어 전송해야함
  - 즉, 공격자가 만든 악성 페이지는 이 토큰 값을 모를 수 밖에 없기 때문에 요청이 거부된다.

2. XSS
 -
공격자가 웹페이지에 악성 스크립트를 삽입하여 다른 사용자가 이 스크립트를 실행하도록 만드는 공격
 
 대응 전략
- 주로입력값 검증과 출력값 처리로 방어한다.

3. 세션 고정
공격자가 사용자의 세션 ID를 미리 정해놓고 사용자가 해당 세션을 사용하도록 유도하는 공격

 대응 전략
Spring Security는 사용자가 로그인 시 새션을 새로 생성하는 방식으로 기본 방어 한다.


4. JWT 탈취
 -
JWT는 인증에 쓰이는 토큰으로, 토큰을 탈취하면 공격자는 이를 이용해 사용자인 척을 할 수 있다.

 대응 전략
 - 
JWT는 본질적으로 탈취에 취약하므로, 아래의 보안 전략들 등을 통해 보호해야한다.
   -
HTTPS 사용
   - 
토큰 만료 기간 설정
   - 
리프레시 토큰 사용
   -
토큰 서명 검증 및 무효화

 

JWT(JSON Web Token)의 구조와 각 구성 요소가 어떤 역할을 하는지 구체적으로 설명하세요.

JWT(JSON Web Token)의 구조

JWT는 세부분으로 나뉘며 각각은  . 으로 구분된다.

  • Header : 어떤 알고리즘으로 서명했는지, 어떤 타입의 토큰인지 정의
  • Payload : 사용자 정보와 클레임(Claim) 데이터가 담김
  • Signature : 헤더와 페이로드가 변조되지 않았음을 검증

JWT의 구조

Header

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg : 사용할 서명 알고리즘 (예 : HMAC SHA256)
  • typ : 토큰 타입(JWT)
  • 이 JSON 객체를 Base64URL로 인코딩하면 JWT의 첫 번째 부분이 된다.

Payload

{
  "sub": "user123",
  "name": "Alice",
  "iat": 1516239022
}
  • Payload 에 담는 정보의 한 ‘조각’ 을 클레임이라고 부르며, name / value 의 한 쌍으로 이뤄진다.
  • 토큰에는 여러개의 클레임 들을 넣을 수 있다.
  • 사용자의 고유 정보와 권한, 토큰 발급 시간(iat) 등이 포함된다.
  • 클레임의 정보는 등록된 (registered) 클레임, 공개 (public) 클레임, 비공개 (private) 클레임으로 세 종류가 있다.
    • 등록된 클레임 : 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들로, 모두 선택적으로 작성이 가능하며 사용할 것을 권장
      • iss: 토큰 발급자(issuer)
      • sub: 토큰 제목(subject)
      • aud: 토큰 대상자(audience)
      • exp: 토큰 만료 시간(expiration)
      • nbf: 토큰 활성 날짜(not before)
      • iat: 토큰 발급 시간(issued at)
      • jti: JWT 토큰 식별자(JWT ID)
    • 공개 클레임 : 사용자 정의 클레임으로, 공개용 정보를 위해 사용된다. 충돌 방지를 위해 URI 포맷을 이용
    • 비공개 클레임 : 사용자 정의 클레임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장
  • 민감한 정보를 직접 담아서는 안 된다.
  • Base64URL로 인코딩하면 두 번째 부분이 된다.

Signature

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)
  • 서버의 비밀 키(Secret Key)로 생성된다.
  • 클라이언트가 보낸 토큰이 변조되지 않았음을 검증한다.

JWT의 동작 흐름

JWT의 동작흐름 이미지

 

나만의 언어로 정리해보기

JWT의 구조
Header
-
어떤 알고리즘으로 서명했는지, 어떤 타입의 토큰인지 정의

Payload
- Payload에 담는 정보의 한 조작을 클레임이라고 부르며, name/value의 한 쌍으로 이루어진다.
토큰에는 여러 개의 클레임들을 넣을 수 있는데, 사용자의 고유 정보와 권한, 토큰 발급 시간 등이 포함된다.
-
 클레임의 정보는 등록된 클레임, 공개 클레임, 비공개 클레임으로 세종류가 있으며, 민감한 정보를 직접 담아서는 안된다.

Signature
 -
서버의 비밀 키로 생성되며, 클라이언트가 보낸 토큰이 변조되지 않았음을 검증한다.

'코드잇 BE스프린트' 카테고리의 다른 글

위클리 페이퍼 - 16주차  (0) 2026.05.04
위클리 페이퍼 - 15주차  (0) 2026.05.01
위클리 페이퍼 - 13주차  (0) 2026.04.29
위클리 페이퍼 - 12주차  (0) 2026.04.29
위클리 페이퍼 - 11주차  (0) 2026.04.28