CSRF

Code_Builder·2024년 8월 19일
0
post-thumbnail

CSRF 란?

공격자가 사용자의 인증 정보를 이용해 사용자가 의도하지 않은 요청을 보내는 보안 취약점

작동방식


이미지 출처 :https://www.indusface.com/blog/how-to-protect-your-web-apps-using-anti-csrf-tokens/

위와 같은 방식으로 csrf 공격이 이루어지는데, 여기서 주요한점은 크롬이나 사파리같은 브라우저는 자동으로 해당 요청을 사용자의 인증 정보(세션,쿠키)와 함께 전송함 그래서 서버는 요청이 유효하다고 간주
-> 사용자가 의도치 않게 공격자가 원하는대로 악의적인 작업이 수행됨


대응책

1. CSRF 토큰 사용

각 요청에 대해 고유한 CSRF 토큰을 생성하고, 이 토큰을 폼에 포함시킴
또한 서버는 요청을 수신할 때, 이 토큰이 세션에 저장된 토큰과 일치하는지 검증,
일치하지 않으면 요청을 거부

예시 코드
(프론트)
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSRF Protection Example</title>
</head>
<body>
    <form method="POST" action="/submit">
    	<!--실제 사용자는 csrf 토큰 인풋박스와 전송하는지도 모름-->
        <input type="hidden" name="csrf_token" value="${csrfToken}">
        <input type="text" name="data" placeholder="Enter some data" required>
        <button type="submit">Submit</button>
    </form>
</body>
</html>
서버 측 예시 코드
    @GetMapping("/")
    public ModelAndView index(HttpSession session) {
        String csrfToken = generateCsrfToken();
        session.setAttribute("csrfToken", csrfToken);
        ModelAndView modelAndView = new ModelAndView("index");
        modelAndView.addObject("csrfToken", csrfToken);
        return modelAndView;
    }

    @PostMapping("/submit")
    public String submit(@RequestParam("data") String data, 
                         @RequestParam("csrf_token") String csrfToken, 
                         HttpSession session) {
        // 세션에 저장된 CSRF 토큰과 비교
        String sessionToken = (String) session.getAttribute("csrfToken");
        if (sessionToken == null || !sessionToken.equals(csrfToken)) {
            return "CSRF token is invalid!";
        }
        return "Data received: " + data;
    }

    private String generateCsrfToken() {
        SecureRandom secureRandom = new SecureRandom();
        byte[] token = new byte[16];
        secureRandom.nextBytes(token);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(token);
    }

2. SameSite 쿠키 속성

쿠키에 SameSite 속성을 설정하여, 외부 사이트에서의 요청 시 쿠키가 전송되지 않도록함

SameSite: 쿠키가 다른 사이트에서 오는 요청에 대해 어떻게 반응할지를 설정

  • SameSite=Strict: 쿠키가 오직 동일한 사이트에서의 요청에만 포함
  • SameSite=Lax: 쿠키가 동일한 사이트에서의 요청과 일부 안전한 요청
  • SameSite=None: 쿠키가 모든 요청에 포함(HTTPS를 통해서만 전송)

3. Referer 또는 Origin 헤더 검사

요청의 Referer 또는 Origin 헤더를 확인하여, 요청이 신뢰할 수 있는 출처에서 온 것인지 검증
-> 신뢰할 수 없는 출처에서 온 요청은 차단

Referer Header: 현재 요청을 보내기 전에 방문한 페이지의 URL

Ex) example.com/page1 에서 example.com/page2 로 이동하면,
page2에 대한 요청example.com/page1 헤더를 포함

Origin Header: 요청이 발생한 사이트의 프로토콜, 도메인, 포트를 포함(=요청을 보낸 출처의 정보)

Ex) example.com에서 API 요청을 보내면, 요청에는 example.com이라는 헤더가 포함(원래의 헤더정보 포함)

profile
사소한일에도 최선을 다하기

0개의 댓글

관련 채용 정보