CSRF란?

2023. 6. 11. 17:45·🥑 Web Technoloy

  • 공부를 하며 강의 내용을 따라하다가 csrf().disable()이라는 코드를 무의식적으로 따라했던 기억이 있습니다.
  • 당시에는 그냥 개발과 테스트에 방해가 되지 않도록 Spring Security에서 제공해주는 보안 기능을 잠시 비활성화시킨다는 개념으로 사용했으나, 시간이 지나고 우연히 이와 관련된 내용을 보니 그보다 주요한 목적이 있는 것 같아 이를 찾아서 정리해보았습니다.

그때 그 시절 코드...

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig implements WebMvcConfigurer {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()  
                .antMatchers("/", "/auth/**", "/js/**", "/css/**", "/image/**", "/sort/**", "/board", "/upload/**")
                .permitAll()
                .anyRequest()
                .authenticated()
            .and()
            .formLogin()
                .loginPage("/auth/loginForm")
                .loginProcessingUrl("/auth/loginProc")
                .failureHandler(userLoginFailHandler)
                .defaultSuccessUrl("/");

        return http.build();
    }
}

💡 CSRF(Cross Site Request Forgery)

  • CSRF 공격이란 웹 애플리케이션 취약점 중 하나로, 인터넷 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격입니다.
  • 즉, CSRF를 통해 해커는 사용자의 권한을 도용하여 중요 기능을 실행하는 것이 가능합니다.
  • 참고로, CSRF는 해커가 사용자의 컴퓨터를 감염시키거나 페이스북 서버를 해킹을 해서 이뤄지는 공격은 아닙니다. 그래서 CSRF 공격이 이뤄지려면 다음과 같은 조건이 만족되어야 합니다.
    • 위조 요청을 전송하는 서비스에 사용자가 로그인 한 상태인 경우
    • 사용자가 해커가 만든 피싱 사이트에 접속한 경우
  • 보통 자주 사용하는 사이트의 경우 자동 로그인을 해놓는 경우가 많고, 해커가 만든 피싱 사이트가 아니라 XSS 공격을 성공한 정상 사이트를 통해서도 CSRF 공격이 수행될 수 있기 때문에 충분히 가능한 공격 기법이라고 할 수 있습니다.

💡 CSRF 공격 방어

  • CSRF 공격을 막기 위한 방법으로는 대표적으로 두 가지가 있습니다.
    • Referer 검증
    • CSRF Token 검증

 

✔ Referer 검증

  • Referer이란 현재 표시하는 웹 페이지가 어떤 웹 페이지에서 요청되었는지, 어떤 웹 페이지나 웹 서버에서 방문자가 왔는지를 확인할 수 있도록 해주는 HTTP Request Header의 요소를 말합니다.
  • Referer 검증은 이를 활용하여 Back-end 단에서 Request의 Referrer를 확인하여 도메인(ex. *.facebook.com)이 일치하는지 검증하는 방법으로, 해당 요청이 적절한 위치에서 전달된 요청이 아닐 경우 예외를 발생시켜 이를 막습니다.
  • 일반적으로는 Referrer 검증만으로 대부분의 CSRF 공격을 방어할 수 있습니다.
  • 다만 같은 도메인 내의 페이지에 XSS 취약점이 있는 경우 CSRF 공격에 취약해질 수 있습니다.
  • 따라서 도메인 단위 검증에서 좀 더 세밀하게 페이지 단위까지 일치하는지 검증해야 도메인 내 타 페이지에서의 XSS 취약점에 의한 CSRF 공격까지 방어할 수 있습니다.

 

✔ CSRF Token 검증

  • Referrer 검증이 불가한 환경이라면, CSRF Token를 활용할 수 있습니다.
  • 우선 사용자의 세션에 임의의 난수 값을 저장하고 사용자의 요청마다 해당 난수 값을 포함시켜 전송시킵니다.
  • 이후 Back-end 단에서 요청을 받을 때마다 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는 지 검증하여 적절한 요청인지 확인합니다.
  • 이 방법도 결국 같은 도메인 내에 XSS 취약점이 있다면 CSRF 공격에 취약해집니다.
  • 아래는 간략한 샘플 코드입니다.
// 로그인시, 또는 작업화면 요청시 CSRF 토큰을 생성하여 세션에 저장한다.
session.setAttribute("CSRF_TOKEN",UUID.randomUUID().toString());

// 요청 페이지에 CSRF 토큰을 셋팅하여 전송한다
<input type="hidden" name="_csrf" value="${CSRF_TOKEN}" />
// 파라미터로 전달된 csrf 토큰 값
String param = request.getParameter("_csrf");

// 세션에 저장된 토큰 값과 일치 여부 검증
if (request.getSession().getAttribute("CSRF_TOKEN").equals(param)) {
    return true;
} else {
    response.sendRedirect("/");
    return false;
}

💡 CSRF 방어 기능을 마음대로 비활성화 해도 될까?

  • 앞에서, 필자는 개발을 할 때 Spring Security에서 기본으로 제공해주는 CSRF 방어 기능을 비활성화 했다고 했습니다.
  • Spring Security는 웹 사이트 취약점 공격을 방지하기 위해 CSRF 토큰 값을 세션을 통해 발행하고 웹 페이지에서는 폼 전송시에 해당 토큰을 함께 전송하여 실제 웹 페이지에서 작성된 데이터가 전달되는지를 검증하기 때문에, 개발시 테스트 수행을 위한 요청까지 모두 막아버리기 때문입니다.
  • 그렇다고 보안 기능을 이렇게 마음대로 비활성화 해도 되는 걸까요?
  • 공식 문서를 살펴보면 언제 CSRF protection 기능을 사용해야 하는지 명시되어 있습니다.

  • 위 내용에서 CSRF protecton 기능은 브라우저를 통해 Request를 받을 때 사용하라고 적혀 있습니다.
  • 즉, 브라우저를 통해 Request를 받지 않는다면 사용하지 않아도 된다고 해석할 수 있습니다.
  • 따라서 SPA(Single Page Application) 방식으로 개발된 REST API 서버는 해당 기능을 비활성화해도 크게 상관이 없다고 할 수 있습니다.
    • 💬 왜 그런가요?
      • REST API 서버는 HTTP 형식을 따르기 때문에 무상태(stateless)이며, 때문에 서버쪽의 세션이나 브라우저 쿠키에 의존하지 않습니다.
      • 일반적으로 JWT와 같은 토큰을 사용하여 인증하기 때문에 해당 토큰을 Cookie에 저장하지 않는다면 CSRF 취약점에 대해서는 이미 어느 정도 안전하다고 말할 수 있습니다.
  • 정리하자면 세션을 사용할 때 발생하는 취약점인 CSRF에 대해서 100%라고 장담할 수는 없지만 취약점 발생 요소가 제거되었기 때문에 CSRF protection 기능을 비활성화 하더라도 큰 문제가 되지 않는 것입니다.

📌 References

  • https://itstory.tk/entry/CSRF-%EA%B3%B5%EA%B2%A9%EC%9D%B4%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-CSRF-%EB%B0%A9%EC%96%B4-%EB%B0%A9%EB%B2%95
  • https://zzang9ha.tistory.com/341
  • https://wave1994.tistory.com/150
저작자표시 (새창열림)

'🥑 Web Technoloy' 카테고리의 다른 글

AJAX란?  (0) 2023.06.13
RESTful API란?  (0) 2023.06.13
URI와 URL  (0) 2023.06.06
JPQL과 QueryDSL  (0) 2023.06.04
JPA와 Hibernate 그리고 Spring Data JPA  (0) 2023.06.04
'🥑 Web Technoloy' 카테고리의 다른 글
  • AJAX란?
  • RESTful API란?
  • URI와 URL
  • JPQL과 QueryDSL
Baeg-won
Baeg-won
  • Baeg-won
    좋았다면 추억이고 나빴다면 경험이다.
    Baeg-won
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 🍃 Spring, Spring Boot
        • 스프링 프레임워크 기초
        • 스프링 핵심 원리 - 기본편
        • 자바 ORM 표준 JPA 프로그래밍 - 기본편
        • 스프링 MVC
        • 실전! 스프링 부트와 JPA 활용1 - 웹 애플리..
      • 🥑 Web Technoloy
      • 🚗 Backend Toy Project
        • 스프링 부트 게시판
        • Photogram
        • Baeg-won Clothing Gallery
      • 🥇 Problem Solving
        • Breadth-First Search
        • Depth-First Search
        • Backtracking
        • Simulation
        • Two-pointer
        • Binary Search
        • Greedy
        • Dynamic Programming
        • Minimum Spanning Tree
        • Dijkstra
        • Floyd warshall
      • ☕ Java
        • 명품 자바 에센셜
        • Applications
      • 🍦 JavaScript
        • JavaScript 기초
      • 🐧 Linux
        • 이것이 리눅스다(CentOS 8)
      • 📟 Database
        • 혼자 공부하는 SQL
      • 🧬 Data Structure
      • 🎬 HTML
      • 🎤 Tech Interview
      • 📌 etc
        • Unity 2D Raising Jelly Game
        • C++
        • 영어 쉐도잉
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Baeg-won
CSRF란?
상단으로

티스토리툴바