CSRF

1=1·2024년 1월 13일
0

SK shieldus 16

목록 보기
10/10

CSRF 란 ?

Cross Site Request Forgery 의 약자로 한글 뜻으로는 사이트 간 요청 위조를 뜻함

  • 웹 보안 취약점의 일종
  • 자신의 의지와 무관하게 공격자가 의도한 행위를 특정 웹 사이트에 요청하게 하는 공격
  • 공격자는 사용자의 계정에 대한 완전한 제어권을 얻을 수 있음
  • ex ) 피해자의 전자 메일 주소 변경, 암호 변경, 자금이체 등의 행위

CSRF 동작원리

  • CSRF 가 동작되려면

    1. 사용자가 보안이 취약한 서버로부터 이미 로그인 되어있는 상태여야 한다
    2. 쿠키 기반의 서버 세션 정보를 획득할 수 있어야 함
    3. 공격자는 서버를 공격하기 위한 요청 방법에 대해 미리 파악하고 예상치 못한 요청 매개 변수가 없어야함

  • 동작순서

1) 사용자가 보안에 취약한 서버에 로그인 한다
2) 서버에 저장된 세션 정보를 사용할 수 있는 session ID가 사용자의 브라우저 쿠키에 저장된다
3) 공격자는 사용자가 악성 스크립트 페이지를 누르도록 유도한다

ex )

  • 게시판이 있는 웹사이트에 악성 스크립트를 게시글로 작성하여 사용자들이 게시글을 클릭하도록 유도
  • 메일 등으로 악성 스크립트를 직접 전달하거나, 악성 스크립트가 적힌 페이지 링크를 전달

4) 사용자가 악성 스크립트가 작성된 페이지 접근시 웹 브라우저에 의해 쿠키에 저장된 session ID와 함께 서버로 요청
5) 서버는 쿠키에 담긴 session ID를 통해 해당 요청이 인증된 사용자로부터 온 것으로 판단하고 처리


  • 웹 페이지 vs 웹 사이트
  1. 웹 페이지
    firefox, 구글 크롬, 오페라, MS 익스플로러, 엣지 등 웹 브라우저에서 보여지는 문서 -> "페이지"라고 하기도함
  2. 웹 사이트
    다양한 방식으로 그룹으로 묶이거나 연결된 웹 페이지들의 모음 -> "웹 사이트"나 단순히 "사이트" 라고도 한다
  3. 웹 서버
    인터넷에 웹 사이트를 호스팅하는 컴퓨터
  4. 검색엔진
    구글, 빙, 야후 같은 다른 웹 페이지들을 찾게 도와주는 웹 사이트
  5. 웹 브라우저
    인터넷에서 웹 사이트를 보는 컴퓨터 또는 장치의 응용 프로그램

  • 도서관 vs 웹 페이지
    - 도서관 == 웹서버
    - 도서관에 있는 과학, 수학, 역사와 같은 각기 다른 구역들 == 웹 사이트
    - 구역에 있는 책들 == 웹 페이지
    - 검색 색인 == 검색 엔진

CSRF 방어 방법 - 사용자 입장

이상한 URL을 클릭하지 않고 의심이 되는 메일을 열어보지 않음
: CSRF는 클릭만 해도 의도하지 않은 동작이 수행될 수 있기 때문


CSRF 방어 방법 - 웹 개발자/운영자 입장

  1. Referer check
    • HTTP 요청 헤더 정보에서 Refferer 정보 확인 가능 ( 일반적으로 호스트와 referrer 값이 일치하므로 둘을 비교 )
    • csrf 공격의 대부분 referrer 값에 대한 검증만으로 많은 수의 공격 방어 가능

  2. CAPTCHA 도입
    웹 사이트와 서비스를 이용하는 사용자가 실제 인간인지 파악하고 컴퓨터로 인해 발생할 수 있는 다양한 문제를 방지하는데 중요한 역할을 한다.

< 캡챠가 없다면? >

  • 설문결과 조작
  • 하나의 웹 사이트나 서비스에 단시간에 여러 계정으로 로그인
  • 단시간에 수많은 계정 생성
  • 사람만 이용하도록 설계된 웹사이트나 서비스에 침투

  1. Security Token 사용 ( CSRF Token )
    사용자의 세션에 임의의 난수 값을 저장하고 사용자의 요청마다 해당 난수 값을 포함시켜 전송시킨다. 후에 백엔드 단에서 요청을 받을 때마다 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는지 검증하는 방법이다.
    이 방법도 도메인 내에 xss 취약점이 있다면 CSRF 공격에 취약해진다

# 로그인시 또는 작업화면 요청시 CSRF 토큰을 생성하여 세션에 저장
session.setAttribute("CSRF_TOKEN", UUID, randomUUID().toString());

# 요청 페이지에 CSRF 토큰을 세팅하여 전송
<input type="hidden" name="_scrf" value="${CSRF_TOKEN}" />

# 파라미터로 전달된 csrf 토큰 값
String param = request.getParameter("_csrf");

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

0개의 댓글