백엔드 면접 용어 사전
인증·인가

CSRF

로그인된 사용자의 브라우저를 이용해 의도치 않은 요청을 보내게 하는 공격. 토큰·SameSite로 막는다.

사용자가 로그인된 상태를 악용해, 사용자 의도와 무관한 요청을 보내게 만드는 공격 (Cross-Site Request Forgery).

어떻게 성립하는가 — 브라우저의 자동 쿠키 전송

  • ① 피해자가 bank.com 에 로그인 (세션 쿠키 보유)
  • ② 로그아웃하지 않은 채 attacker.com 방문
  • ③ 그 페이지에 숨겨진 폼이 있다
<form action="https://bank.com/transfer" method="POST">
  • <input type="hidden" name="to" value="공격자계좌">
  • <input type="hidden" name="amount" value="1000000">
</form> <script>document.forms[0].submit();</script>
  • ④ 브라우저는 bank.com 으로 요청하면서 세션 쿠키를 자동으로 붙인다
  • ⑤ 서버 입장에서는 정상 로그인 사용자의 요청 → 이체 실행 ✗

핵심 — 브라우저는 요청 대상 도메인의 쿠키를 누가 요청을 만들었는지와 무관하게 자동으로 붙인다. 이 편의성이 취약점이 된다.

XSS와 무엇이 다른가 — 자주 혼동된다

CSRFXSS
공격 위치다른 사이트에서취약한 사이트 안에서
악용하는 것사용자의 인증 상태사이트의 스크립트 실행 권한
응답을 읽나못 읽는다(SOP)읽는다
할 수 있는 것요청 보내기만사실상 무엇이든
위험도높음더 높음

CSRF는 요청만 보낼 뿐 응답을 볼 수 없다. 동일 출처 정책 때문이다. 그래서 "이체"는 가능해도 "잔액 조회 후 유출"은 불가능하다.

XSS가 있으면 CSRF 방어는 무의미하다 — 스크립트로 토큰을 읽어 함께 보내면 되기 때문이다. 그래서 XSS 방어가 우선순위가 높다.

방어 ① — CSRF 토큰

  • ① 서버가 예측 불가능한 토큰을 발급해 폼에 심는다

  • ② 요청 시 그 토큰을 함께 보낸다

  • ③ 서버가 세션에 저장된 값과 대조

  • 공격자는 이 토큰 값을 알 수 없다

  • 다른 사이트에서 응답을 읽을 수 없으므로(SOP) 토큰을 훔칠 방법이 없다

Double Submit Cookie — 서버 저장 없이, 같은 값을 쿠키와 요청 본문에 동시에 넣어 비교하는 변형. 무상태로 구현할 수 있다.

방어 ② — SameSite 쿠키 (현대의 기본 방어선)

Set-Cookie: SID=abc; SameSite=Lax
동작
Strict외부 사이트발 요청에 절대 안 붙음. 가장 안전하나 외부 링크 이동 시 로그인이 풀린 것처럼 보임
LaxGET 최상위 이동에만 붙음. POST에는 안 붙음 → CSRF 대부분 차단
None항상 붙음. Secure 필수

현대 브라우저는 Lax가 기본값이라 CSRF 위험이 크게 줄었다. 다만 오래된 브라우저SameSite=None이 필요한 구성에서는 여전히 토큰이 필요하다.

방어 ③ — Origin/Referer 검증

요청 헤더의 출처가 우리 도메인인지 확인한다. 간단하지만 프록시·프라이버시 설정으로 헤더가 없을 수 있어 보조 수단으로 쓴다.

언제 CSRF 방어가 필요 없나 — 중요한 판단

CSRF는 "브라우저가 인증 정보를 자동으로 붙인다"는 전제에서 성립한다

  • 세션 쿠키 인증 — → CSRF 방어 필요 ✅
  • Authorization 헤더의 JWT → 필요 없음
    • (헤더는 브라우저가 자동으로 붙이지 않는다. JS가 명시적으로 넣어야 한다)
  • JWT를 쿠키에 저장 — → 필요하다! 쿠키인 이상 자동 전송된다

"JWT를 쓰니까 CSRF는 신경 안 써도 된다"는 흔한 오해다. 어디에 저장했는지가 기준이다.

// REST API + Bearer 토큰이면 비활성화가 맞다
http.csrf(csrf -> csrf.disable());

다만 "에러가 나서 껐다" 는 것은 위험하다. 인증 방식을 근거로 판단해야 한다.

GET은 상태를 바꾸면 안 된다

❌ GET /delete?id=1

  • <img src="https://site.com/delete?id=1"> 만으로 공격 성립
  • SameSite=Lax 로도 GET은 막히지 않는 경우가 있다 상태 변경은 POST/PUT/DELETE로. REST의 안전성 원칙이 보안과 직결되는 지점이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 인증·인가 — 세션·JWT·OAuth 2.1·CSRF