--- title: official-doc / Spring Security — Cross Site Request Forgery (CSRF) Protection (Servlet) source_type: official-doc url: https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html archive_url: related_branches: [feature-keycloak-bff-csrf-samesite-defense] related_projects: [] tags: [official-doc, keycloak-patterns, security, auth, spring-security] created: 2026-07-23 --- # official-doc / Spring Security — Cross Site Request Forgery (CSRF) Protection (Servlet) > Layer: `raw/official-docs/` — Spring Security 공식 레퍼런스(Servlet 스택) "Cross Site Request Forgery (CSRF)" 페이지의 원문 발췌. `feature-keycloak-bff-csrf-samesite-defense` branch의 AP3(BFF, `oauth2Login` cookie-session 패턴) CSRF 방어 메커니즘 결정(D3) 및 defense-in-depth 결정(D4) 근거로 보관. ## Parent / 활용 branch (필수) | Branch | 이 자료가 정당화하는 결정 | |---|---| | [[raw/branch-notes/feature-keycloak-bff-csrf-samesite-defense]] | AP3 BFF(Spring `oauth2Login` cookie-session) 패턴에서 CSRF 토큰 방어 메커니즘(D3: synchronizer token / `CookieCsrfTokenRepository` / BREACH 방어)의 공식 벤더 근거. D4(defense-in-depth: CSRF token + SameSite 조합)에 대해서는 이 문서가 SameSite를 전혀 언급하지 않으므로 **부분 근거만 제공** — 아래 Usage Boundaries 참조 | ## 출처 - 원본 URL: https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html - 아카이브 URL: (미수집) - 저자 / 조직: Spring Security (VMware/Broadcom) — 공식 레퍼런스 문서 - 발행일: 고정 발행일 없음 (rolling reference doc). 확인 시점 페이지 하단 버전 배너: Stable `7.1.0` / `7.0.6` / `6.5.11`, Snapshot `7.1.1-SNAPSHOT` / `7.0.7-SNAPSHOT` / `6.5.12-SNAPSHOT` - 마지막 확인일: 2026-07-23 ## 왜 저장했는지 AP3(BFF) 패턴은 OAuth2/OIDC 토큰을 backend session에 두고 browser에는 session cookie만 노출한다(브랜치 상속 결정 `DEC-KEYCLOAK-PATTERNS-OVERVIEW-BFF-SESSION-001@1`). 이 쿠키 기반 세션은 CSRF에 노출되므로, branch는 Spring Security가 실제로 구현하는 CSRF 방어 메커니즘(synchronizer token pattern, `CookieCsrfTokenRepository`, BREACH 방어)을 공식 문서로 확인해야 한다. 단, 이 특정 페이지는 SameSite 쿠키 속성을 전혀 다루지 않아 D4(SameSite 결합) 근거로는 불충분함을 확인하기 위해서도 저장한다. ## 핵심 인용 > [§Cross Site Request Forgery (CSRF), 개요] "Spring Security protects against CSRF attacks by default for unsafe HTTP methods, such as a POST request, so no additional code is necessary." > [§CSRF Considerations › Logging Out] "This ensures that logging out requires a CSRF token and that a malicious user cannot forcibly log your users out." > [§Integrating with CSRF Protection] "For the synchronizer token pattern to protect against CSRF attacks, we must include the actual CSRF token in the HTTP request." > [§Persisting the CsrfToken › Using the CookieCsrfTokenRepository] "The CookieCsrfTokenRepository writes to a cookie named XSRF-TOKEN and reads it from an HTTP request header named X-XSRF-TOKEN or the request parameter _csrf by default." > [§Handling the CsrfToken › Using the XorCsrfTokenRequestAttributeHandler (BREACH)] "BREACH protection is provided by encoding randomness into the CSRF token value to ensure the returned CsrfToken changes on every request." ## 추출된 주장 > `Claim ID` prefix: `SPRINGSEC-CSRF`. | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | SPRINGSEC-CSRF-C1 | Spring Security는 POST 등 unsafe HTTP method 요청에 대해 기본적으로 CSRF 공격을 방어하며 별도 설정 코드가 필요 없다 | [§개요] "Spring Security protects against CSRF attacks by default for unsafe HTTP methods, such as a POST request, so no additional code is necessary." | `official-vendor-doc` | `.csrf(Customizer.withDefaults())` 또는 미설정 시 Spring Security 6.x/7.x 기본 동작 | 어떤 매커니즘(synchronizer token / double-submit / SameSite)으로 방어하는지는 이 문장 자체는 규정하지 않음 — 메커니즘은 C3·C4에서 별도 확인 | | SPRINGSEC-CSRF-C2 | CSRF 방어가 없으면 악의적 사용자가 피해자를 강제로 로그아웃(또는 다른 state-changing 요청)시키는 위조 요청(forged request)이 가능하다 — CSRF 토큰 요구가 이를 차단한다 | [§Logging Out] "This ensures that logging out requires a CSRF token and that a malicious user cannot forcibly log your users out." | `official-vendor-doc` | 인증된 세션(쿠키)을 가진 사용자를 대상으로 한 상태 변경(state-changing) 요청 위조 시나리오 일반 | CSRF 공격의 전체 위협 모델(예: 쿠키가 자동 첨부되는 근본 원인, SameSite와의 관계)을 설명하지는 않음 — 이 문장은 logout 시나리오에 한정된 결과 진술 | | SPRINGSEC-CSRF-C3 | Spring Security의 CSRF 방어는 synchronizer token pattern이며, 공격자가 자동으로 재현할 수 없는 실제 CSRF 토큰을 HTTP 요청에 포함시켜야 한다 | [§Integrating with CSRF Protection] "For the synchronizer token pattern to protect against CSRF attacks, we must include the actual CSRF token in the HTTP request." | `official-vendor-doc` | 통합 방식(HTML form / JS / mobile) 무관하게 적용되는 핵심 방어 원리 | 토큰이 세션에 저장되는지 쿠키에 저장되는지는 이 문장만으로 규정하지 않음 — 저장 위치는 `CsrfTokenRepository` 구현체 선택 문제(C4 참조) | | SPRINGSEC-CSRF-C4 | `CookieCsrfTokenRepository`는 `CsrfToken`을 `XSRF-TOKEN`이라는 이름의 쿠키에 쓰고, 기본적으로 `X-XSRF-TOKEN` 요청 헤더 또는 `_csrf` 요청 파라미터로부터 읽는다 | [§Using the CookieCsrfTokenRepository] "The CookieCsrfTokenRepository writes to a cookie named XSRF-TOKEN and reads it from an HTTP request header named X-XSRF-TOKEN or the request parameter _csrf by default." | `official-vendor-doc` | `CsrfTokenRepository`를 `CookieCsrfTokenRepository`로 명시적으로 구성한 JavaScript 기반 애플리케이션(AP3처럼 세션 대신/추가로 쿠키 기반 토큰 노출이 필요한 경우) | 이 쿠키(`XSRF-TOKEN`)의 `SameSite` 속성값(Lax/Strict/None)이 무엇인지는 이 문장이 전혀 규정하지 않음 — `CookieCsrfTokenRepository`의 `SameSite` 기본값/구성 옵션은 이 페이지 범위 밖 | | SPRINGSEC-CSRF-C5 | BREACH 방어는 CSRF 토큰 값에 무작위성(randomness)을 인코딩하여 매 요청마다 반환되는 `CsrfToken` 값이 달라지게 함으로써 제공된다 | [§Using the XorCsrfTokenRequestAttributeHandler (BREACH)] "BREACH protection is provided by encoding randomness into the CSRF token value to ensure the returned CsrfToken changes on every request." | `official-vendor-doc` | 기본 활성화된 `XorCsrfTokenRequestAttributeHandler` 사용 시(Spring Security 6+ 기본값) | BREACH 방어가 `SameSite` 쿠키 속성과 결합되어 있다거나 이를 대체·보완한다는 명제는 이 문장이 증명하지 않음 — BREACH는 CSRF 토큰 값 자체의 압축 사이드채널(compression side-channel) 공격 방어이며, cross-site 요청 자체를 막는 메커니즘이 아님 | ## 적용 경계 - 이 자료가 직접 증명하는 것: - `SPRINGSEC-CSRF-C1`: Spring Security의 CSRF 기본 방어 활성화 범위(unsafe HTTP method) - `SPRINGSEC-CSRF-C2`: CSRF 방어 부재 시 위협 시나리오(강제 로그아웃 등 위조 요청) 예시 - `SPRINGSEC-CSRF-C3`: synchronizer token pattern이 Spring Security CSRF 방어의 핵심 원리라는 사실 - `SPRINGSEC-CSRF-C4`: `CookieCsrfTokenRepository`의 쿠키명(`XSRF-TOKEN`)·요청 헤더명(`X-XSRF-TOKEN`)·파라미터명(`_csrf`) 기본값 - `SPRINGSEC-CSRF-C5`: BREACH 방어의 원리(토큰 값 randomization) - 이 자료가 증명하지 않는 것 (**UNSUPPORTED_DECISION 후보** — branch D4로 그대로 인용 금지): - **이 문서(`servlet/exploits/csrf.html`)는 "SameSite"라는 단어를 단 한 차례도 언급하지 않는다** (원문 전체 대상 대소문자 무시 검색 결과 0건, 2026-07-23 확인). 따라서 branch의 D4("Spring이 CSRF token과 SameSite를 어떻게 combine하는가")를 이 자료 단독으로 정당화할 수 없다. SameSite 쿠키 속성 가이드는 별도 출처(예: Spring Session reference의 쿠키 직렬화 옵션, `server.servlet.session.cookie.same-site` — Spring Boot 공식 문서, 또는 MDN `Set-Cookie` SameSite 사양)가 필요하다. - BREACH 방어(C5)가 SameSite를 대체하거나 SameSite와 결합되어 동작한다는 명제. - `CookieCsrfTokenRepository`가 생성하는 `XSRF-TOKEN` 쿠키의 `SameSite` 기본값 — 이 페이지의 코드 예제(`CookieCsrfTokenRepository.withHttpOnlyFalse()`)는 `SameSite` 파라미터를 전혀 노출하지 않는다. - 내 프로젝트(AP3 BFF)에 적용하려면 추가 확인이 필요한 것: - 실제 세션 쿠키(`JSESSIONID` 등)와 `XSRF-TOKEN` 쿠키 각각에 `SameSite` 속성을 어떻게 지정할지는 Spring Session / `CookieSerializer` 또는 서블릿 컨테이너 설정 별도 확인 필요. - Spring Boot `server.servlet.session.cookie.same-site` 프로퍼티(별도 Spring Boot 공식 문서)와 `CookieCsrfTokenRepository`의 관계 확인 필요 — 이 문서 범위 밖. ## 메모 > 검증되지 않은 내 해석. 사실 인용과 분리. - D3(CSRF 토큰 메커니즘)는 `SPRINGSEC-CSRF-C3`+`C4` 조합으로 충분히 뒷받침 가능해 보인다(미검증 — branch 작성 시 재확인). - D4(defense-in-depth: CSRF token + SameSite)는 이 자료만으로는 뒷받침 불가 — branch-spec 단계에서 SameSite 벤더 자료를 별도로 raw에 등록하거나, 근거 없이 작성 시 `UNSUPPORTED_DECISION` 라벨을 붙여야 한다(미검증 판단, 제안일 뿐). - 추가로 봐야 할 동일 출처 페이지: docs.spring.io의 "CSRF Considerations"(서블릿 비특정 general 챕터), Spring Session reference의 쿠키 직렬화/SameSite 옵션 페이지, Spring Boot `server.servlet.session.cookie.same-site` 레퍼런스. ## 관련 - 같은 주제 다른 official-doc / company-tech-blog: (아직 없음 — 이 branch의 최초 CSRF raw 자료) - 이 자료를 인용한 wiki 요약: `[[wiki/concepts/...]]` (생성 시)